func untagPathsAll(store *storage.Storage, tx *storage.Tx, paths []string, recursive, followSymlinks bool) (error, warnings) { warnings := make(warnings, 0, 10) for _, path := range paths { absPath, err := filepath.Abs(path) if err != nil { return fmt.Errorf("%v: could not get absolute path: %v", path, err), warnings } log.Infof(2, "%v: resolving path", path) stat, err := os.Lstat(absPath) if err != nil { switch { case os.IsNotExist(err), os.IsPermission(err): // ignore default: return err, nil } } else if stat.Mode()&os.ModeSymlink != 0 && followSymlinks { absPath, err = _path.Dereference(absPath) if err != nil { return err, nil } } file, err := store.FileByPath(tx, absPath) if err != nil { return fmt.Errorf("%v: could not retrieve file: %v", path, err), warnings } if file == nil { warnings = append(warnings, fmt.Sprintf("%v: file is not tagged.", path)) continue } log.Infof(2, "%v: removing all tags.", path) if err := store.DeleteFileTagsByFileId(tx, file.Id); err != nil { return fmt.Errorf("%v: could not remove file's tags: %v", path, err), warnings } if recursive { childFiles, err := store.FilesByDirectory(tx, file.Path()) if err != nil { return fmt.Errorf("%v: could not retrieve files for directory: %v", path, err), warnings } for _, childFile := range childFiles { if err := store.DeleteFileTagsByFileId(tx, childFile.Id); err != nil { return fmt.Errorf("%v: could not remove file's tags: %v", childFile.Path(), err), warnings } } } } return nil, warnings }
func manualRepair(store *storage.Storage, tx *storage.Tx, fromPath, toPath string, pretend bool) error { absFromPath, err := filepath.Abs(fromPath) if err != nil { return fmt.Errorf("%v: could not determine absolute path", err) } absToPath, err := filepath.Abs(toPath) if err != nil { return fmt.Errorf("%v: could not determine absolute path", err) } log.Infof(2, "retrieving files under '%v' from the database", fromPath) dbFile, err := store.FileByPath(tx, absFromPath) if err != nil { return fmt.Errorf("%v: could not retrieve file: %v", fromPath, err) } if dbFile != nil { log.Infof(2, "%v: updating to %v", fromPath, toPath) if !pretend { if err := manualRepairFile(store, tx, dbFile, absToPath); err != nil { return err } } } dbFiles, err := store.FilesByDirectory(tx, absFromPath) if err != nil { return fmt.Errorf("could not retrieve files from storage: %v", err) } for _, dbFile = range dbFiles { relFileFromPath := _path.Rel(dbFile.Path()) absFileToPath := strings.Replace(dbFile.Path(), absFromPath, absToPath, 1) relFileToPath := _path.Rel(absFileToPath) log.Infof(2, "%v: updating to %v", relFileFromPath, relFileToPath) if !pretend { if err := manualRepairFile(store, tx, dbFile, absFileToPath); err != nil { return err } } } return nil }
func statusPaths(store *storage.Storage, tx *storage.Tx, paths []string, dirOnly bool) (*StatusReport, error) { report := NewReport() for _, path := range paths { absPath, err := filepath.Abs(path) if err != nil { return nil, fmt.Errorf("%v: could not get absolute path: %v", path, err) } file, err := store.FileByPath(tx, absPath) if err != nil { return nil, fmt.Errorf("%v: could not retrieve file: %v", path, err) } if file != nil { err = statusCheckFile(file, report) if err != nil { return nil, err } } if !dirOnly { log.Infof(2, "%v: retrieving files from database.", path) files, err := store.FilesByDirectory(tx, absPath) if err != nil { return nil, fmt.Errorf("%v: could not retrieve files for directory: %v", path, err) } err = statusCheckFiles(files, report) if err != nil { return nil, err } } err = findNewFiles(absPath, report, dirOnly) if err != nil { return nil, err } } return report, nil }
func untagPathsAll(store *storage.Storage, tx *storage.Tx, paths []string, recursive bool) (error, warnings) { warnings := make(warnings, 0, 10) for _, path := range paths { absPath, err := filepath.Abs(path) if err != nil { return fmt.Errorf("%v: could not get absolute path: %v", path, err), warnings } file, err := store.FileByPath(tx, absPath) if err != nil { return fmt.Errorf("%v: could not retrieve file: %v", path, err), warnings } if file == nil { warnings = append(warnings, fmt.Sprintf("%v: file is not tagged.", path)) continue } log.Infof(2, "%v: removing all tags.", file.Path()) if err := store.DeleteFileTagsByFileId(tx, file.Id); err != nil { return fmt.Errorf("%v: could not remove file's tags: %v", file.Path(), err), warnings } if recursive { childFiles, err := store.FilesByDirectory(tx, file.Path()) if err != nil { return fmt.Errorf("%v: could not retrieve files for directory: %v", file.Path()), warnings } for _, childFile := range childFiles { if err := store.DeleteFileTagsByFileId(tx, childFile.Id); err != nil { return fmt.Errorf("%v: could not remove file's tags: %v", childFile.Path(), err), warnings } } } } return nil, warnings }
func statusPaths(store *storage.Storage, tx *storage.Tx, paths []string, dirOnly, followSymlinks bool) (*StatusReport, error) { report := NewReport() for _, path := range paths { absPath, err := filepath.Abs(path) if err != nil { return nil, fmt.Errorf("%v: could not get absolute path: %v", path, err) } log.Infof(2, "%v: resolving file", path) resolvedPath := absPath stat, err := os.Lstat(absPath) if err != nil { switch { case os.IsNotExist(err), os.IsPermission(err): stat = emptyStat{} default: return nil, fmt.Errorf("%v: could not stat path: %v", path, err) } } else if stat.Mode()&os.ModeSymlink != 0 { resolvedPath, err = _path.Dereference(absPath) if err != nil { return nil, fmt.Errorf("%v: could not dereference symbolic link: %v", path, err) } } log.Infof(2, "%v: checking file in database", path) file, err := store.FileByPath(tx, resolvedPath) if err != nil { return nil, fmt.Errorf("%v: could not retrieve file: %v", path, err) } if file != nil { err = statusCheckFile(absPath, file, report) if err != nil { return nil, err } } if !dirOnly && (stat.Mode()&os.ModeSymlink == 0 || followSymlinks) { log.Infof(2, "%v: retrieving files from database.", path) files, err := store.FilesByDirectory(tx, resolvedPath) if err != nil { return nil, fmt.Errorf("%v: could not retrieve files for directory: %v", path, err) } err = statusCheckFiles(files, report) if err != nil { return nil, err } } err = findNewFiles(absPath, report, dirOnly, followSymlinks) if err != nil { return nil, err } } return report, nil }
func untagPaths(store *storage.Storage, tx *storage.Tx, paths, tagArgs []string, recursive, followSymlinks bool) (error, warnings) { warnings := make(warnings, 0, 10) files := make(entities.Files, 0, len(paths)) for _, path := range paths { absPath, err := filepath.Abs(path) if err != nil { return fmt.Errorf("%v: could not get absolute path: %v", path, err), warnings } log.Infof(2, "%v: resolving path", path) stat, err := os.Lstat(absPath) if err != nil { switch { case os.IsNotExist(err), os.IsPermission(err): // ignore default: return err, nil } } else if stat.Mode()&os.ModeSymlink != 0 && followSymlinks { absPath, err = _path.Dereference(absPath) if err != nil { return err, nil } } file, err := store.FileByPath(tx, absPath) if err != nil { return fmt.Errorf("%v: could not retrieve file: %v", path, err), warnings } if file == nil { warnings = append(warnings, fmt.Sprintf("%v: file is not tagged", path)) continue } files = append(files, file) if recursive { childFiles, err := store.FilesByDirectory(tx, file.Path()) if err != nil { return fmt.Errorf("%v: could not retrieve files for directory: %v", file.Path()), warnings } files = append(files, childFiles...) } } for _, tagArg := range tagArgs { tagName, valueName := parseTagEqValueName(tagArg) tag, err := store.TagByName(tx, tagName) if err != nil { return fmt.Errorf("could not retrieve tag '%v': %v", tagName, err), warnings } if tag == nil { warnings = append(warnings, fmt.Sprintf("no such tag '%v'", tagName)) continue } value, err := store.ValueByName(tx, valueName) if err != nil { return fmt.Errorf("could not retrieve value '%v': %v", valueName, err), warnings } if value == nil { warnings = append(warnings, fmt.Sprintf("no such value '%v'", valueName)) continue } for _, file := range files { if err := store.DeleteFileTag(tx, file.Id, tag.Id, value.Id); err != nil { switch err.(type) { case storage.FileTagDoesNotExist: exists, err := store.FileTagExists(tx, file.Id, tag.Id, value.Id, false) if err != nil { return fmt.Errorf("could not check if tag exists: %v", err), warnings } if exists { if value.Id != 0 { warnings = append(warnings, fmt.Sprintf("%v: cannot remove '%v=%v': delete implication to remove this tag.", file.Path(), tag.Name, value.Name)) } else { warnings = append(warnings, fmt.Sprintf("%v: cannot remove '%v': delete implication to remove this tag.", file.Path(), tag.Name)) } } else { if value.Id != 0 { warnings = append(warnings, fmt.Sprintf("%v: file is not tagged '%v=%v'.", file.Path(), tag.Name, value.Name)) } else { warnings = append(warnings, fmt.Sprintf("%v: file is not tagged '%v'.", file.Path(), tag.Name)) } } default: return fmt.Errorf("%v: could not remove tag '%v', value '%v': %v", file.Path(), tag.Name, value.Name, err), warnings } } } } return nil, warnings }
func fullRepair(store *storage.Storage, tx *storage.Tx, searchPaths []string, limitPath string, removeMissing, recalcUnmodified, rationalize, pretend bool) error { absLimitPath := "" if limitPath != "" { var err error absLimitPath, err = filepath.Abs(limitPath) if err != nil { return fmt.Errorf("%v: could not determine absolute path", err) } } settings, err := store.Settings(tx) if err != nil { return err } log.Infof(2, "retrieving files under '%v' from the database", absLimitPath) dbFiles, err := store.FilesByDirectory(tx, absLimitPath) if err != nil { return fmt.Errorf("could not retrieve files from storage: %v", err) } dbFile, err := store.FileByPath(tx, absLimitPath) if err != nil { return fmt.Errorf("could not retrieve file from storage: %v", err) } if dbFile != nil { dbFiles = append(dbFiles, dbFile) } log.Infof(2, "retrieved %v files from the database for path '%v'", len(dbFiles), absLimitPath) unmodfied, modified, missing := determineStatuses(dbFiles) if recalcUnmodified { if err = repairUnmodified(store, tx, unmodfied, pretend, settings); err != nil { return err } } if err = repairModified(store, tx, modified, pretend, settings); err != nil { return err } if err = repairMoved(store, tx, missing, searchPaths, pretend, settings); err != nil { return err } if err = repairMissing(store, tx, missing, pretend, removeMissing); err != nil { return err } if err = deleteUntaggedFiles(store, tx, dbFiles); err != nil { return err } if rationalize { if err = rationalizeFileTags(store, tx, dbFiles); err != nil { return err } } return nil }