Beispiel #1
0
func tagFrom(store *storage.Storage, tx *storage.Tx, fromPath string, paths []string, explicit, recursive, force, followSymlinks bool) (error, warnings) {
	log.Infof(2, "loading settings")

	settings, err := store.Settings(tx)
	if err != nil {
		return fmt.Errorf("could not retrieve settings: %v", err), nil
	}

	stat, err := os.Lstat(fromPath)
	if err != nil {
		return err, nil
	}
	if stat.Mode()&os.ModeSymlink != 0 && followSymlinks {
		fromPath, err = _path.Dereference(fromPath)
		if err != nil {
			return err, nil
		}
	}

	file, err := store.FileByPath(tx, fromPath)
	if err != nil {
		return fmt.Errorf("%v: could not retrieve file: %v", fromPath, err), nil
	}
	if file == nil {
		return fmt.Errorf("%v: path is not tagged", fromPath), nil
	}

	fileTags, err := store.FileTagsByFileId(tx, file.Id, true)
	if err != nil {
		return fmt.Errorf("%v: could not retrieve filetags: %v", fromPath, err), nil
	}

	pairs := make([]entities.TagIdValueIdPair, len(fileTags))
	for index, fileTag := range fileTags {
		pairs[index] = entities.TagIdValueIdPair{fileTag.TagId, fileTag.ValueId}
	}

	warnings := make(warnings, 0, 10)

	for _, path := range paths {
		if err := tagPath(store, tx, path, pairs, explicit, recursive, force, followSymlinks, settings.FileFingerprintAlgorithm(), settings.DirectoryFingerprintAlgorithm(), settings.SymlinkFingerprintAlgorithm(), settings.ReportDuplicates()); err != nil {
			switch {
			case os.IsPermission(err):
				warnings = append(warnings, fmt.Sprintf("%v: permisison denied", path))
			case os.IsNotExist(err):
				warnings = append(warnings, fmt.Sprintf("%v: no such file", path))
			default:
				return fmt.Errorf("%v: could not stat file: %v", path, err), warnings
			}
		}
	}

	return nil, warnings
}
Beispiel #2
0
func listAllSettings(store *storage.Storage, tx *storage.Tx) error {
	settings, err := store.Settings(tx)
	if err != nil {
		return fmt.Errorf("could not retrieve settings: %v", err)
	}

	for _, setting := range settings {
		printSettingAndValue(setting.Name, setting.Value)
	}

	return nil
}
Beispiel #3
0
func findDuplicatesOf(store *storage.Storage, tx *storage.Tx, paths []string, recursive bool) (error, warnings) {
	settings, err := store.Settings(tx)
	if err != nil {
		return err, nil
	}

	warnings := make(warnings, 0, 10)
	for _, path := range paths {
		_, err := os.Stat(path)
		if err != nil {
			switch {
			case os.IsNotExist(err):
				warnings = append(warnings, fmt.Sprintf("%v: no such file", path))
				continue
			case os.IsPermission(err):
				warnings = append(warnings, fmt.Sprintf("%v: permission denied", path))
				continue
			default:
				return err, warnings
			}
		}
	}

	if recursive {
		p, err := filesystem.Enumerate(paths...)
		if err != nil {
			return fmt.Errorf("could not enumerate paths: %v", err), warnings
		}

		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, settings.FileFingerprintAlgorithm(), settings.DirectoryFingerprintAlgorithm(), settings.SymlinkFingerprintAlgorithm())
		if err != nil {
			return fmt.Errorf("%v: could not create fingerprint: %v", path, err), warnings
		}

		if fp == fingerprint.Fingerprint("") {
			continue
		}

		files, err := store.FilesByFingerprint(tx, fp)
		if err != nil {
			return fmt.Errorf("%v: could not retrieve files matching fingerprint '%v': %v", path, fp, err), warnings
		}

		absPath, err := filepath.Abs(path)
		if err != nil {
			return fmt.Errorf("%v: could not determine absolute path: %v", path, err), warnings
		}

		// 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, warnings
}
Beispiel #4
0
func tagPaths(store *storage.Storage, tx *storage.Tx, tagArgs, paths []string, explicit, recursive, force bool) (error, warnings) {
	log.Infof(2, "loading settings")

	settings, err := store.Settings(tx)
	if err != nil {
		return err, nil
	}

	pairs := make(entities.TagIdValueIdPairs, 0, len(tagArgs))
	warnings := make(warnings, 0, 10)

	for _, tagArg := range tagArgs {
		tagName, valueName := parseTagEqValueName(tagArg)

		tag, err := store.TagByName(tx, tagName)
		if err != nil {
			return err, warnings
		}
		if tag == nil {
			if settings.AutoCreateTags() {
				tag, err = createTag(store, tx, tagName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such tag '%v'", tagName))
				continue
			}
		}

		value, err := store.ValueByName(tx, valueName)
		if err != nil {
			return err, warnings
		}
		if value == nil {
			if settings.AutoCreateValues() {
				value, err = createValue(store, tx, valueName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such value '%v'", valueName))
				continue
			}
		}

		pairs = append(pairs, entities.TagIdValueIdPair{tag.Id, value.Id})
	}

	for _, path := range paths {
		if err := tagPath(store, tx, path, pairs, explicit, recursive, force, settings.FileFingerprintAlgorithm(), settings.DirectoryFingerprintAlgorithm(), settings.SymlinkFingerprintAlgorithm(), settings.ReportDuplicates()); err != nil {
			switch {
			case os.IsPermission(err):
				warnings = append(warnings, fmt.Sprintf("%v: permisison denied", path))
			case os.IsNotExist(err):
				warnings = append(warnings, fmt.Sprintf("%v: no such file", path))
			default:
				return fmt.Errorf("%v: could not stat file: %v", path, err), warnings
			}
		}
	}

	return nil, warnings
}
Beispiel #5
0
func addImplications(store *storage.Storage, tx *storage.Tx, tagArgs []string) (error, warnings) {
	log.Infof(2, "loading settings")

	settings, err := store.Settings(tx)
	if err != nil {
		return err, nil
	}

	implyingTagArg := tagArgs[0]
	impliedTagArgs := tagArgs[1:]

	implyingTagName, implyingValueName := parseTagEqValueName(implyingTagArg)

	implyingTag, err := store.TagByName(tx, implyingTagName)
	if err != nil {
		return err, nil
	}
	if implyingTag == nil {
		if settings.AutoCreateTags() {
			implyingTag, err = createTag(store, tx, implyingTagName)
			if err != nil {
				return err, nil
			}
		} else {
			return NoSuchTagError{implyingTagName}, nil
		}
	}

	implyingValue, err := store.ValueByName(tx, implyingValueName)
	if err != nil {
		return err, nil
	}
	if implyingValue == nil {
		if settings.AutoCreateValues() {
			implyingValue, err = createValue(store, tx, implyingValueName)
			if err != nil {
				return err, nil
			}
		} else {
			return NoSuchValueError{implyingValueName}, nil
		}
	}

	warnings := make(warnings, 0, 10)
	for _, impliedTagArg := range impliedTagArgs {
		impliedTagName, impliedValueName := parseTagEqValueName(impliedTagArg)

		impliedTag, err := store.TagByName(tx, impliedTagName)
		if err != nil {
			return err, warnings
		}
		if impliedTag == nil {
			if settings.AutoCreateTags() {
				impliedTag, err = createTag(store, tx, impliedTagName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such tag '%v'", impliedTagName))
				continue
			}
		}

		impliedValue, err := store.ValueByName(tx, impliedValueName)
		if err != nil {
			return err, warnings
		}
		if impliedValue == nil {
			if settings.AutoCreateValues() {
				impliedValue, err = createValue(store, tx, impliedValueName)
				if err != nil {
					return err, warnings
				}
			} else {
				warnings = append(warnings, fmt.Sprintf("no such value '%v'", impliedValueName))
				continue
			}
		}

		log.Infof(2, "adding tag implication of '%v' to '%v'", implyingTagArg, impliedTagArg)

		if err = store.AddImplication(tx, entities.TagIdValueIdPair{implyingTag.Id, implyingValue.Id}, entities.TagIdValueIdPair{impliedTag.Id, impliedValue.Id}); err != nil {
			return fmt.Errorf("cannot add implication of '%v' to '%v': %v", implyingTagArg, impliedTagArg, err), warnings
		}
	}

	return nil, warnings
}
Beispiel #6
0
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
}