Example #1
0
func rationalizeFileTags(store *storage.Storage, tx *storage.Tx, files entities.Files) error {
	log.Infof(2, "rationalizing file tags")

	for _, file := range files {
		fileTags, err := store.FileTagsByFileId(tx, file.Id, false)
		if err != nil {
			return fmt.Errorf("could not determine tags for file '%v': %v", file.Path(), err)
		}

		for _, fileTag := range fileTags {
			if fileTag.Implicit && fileTag.Explicit {
				log.Infof(2, "%v: removing explicit tagging %v as implicit tagging exists", file.Path(), fileTag.TagId)

				if err := store.DeleteFileTag(tx, fileTag.FileId, fileTag.TagId, fileTag.ValueId); err != nil {
					return fmt.Errorf("could not delete file tag for file %v, tag %v and value %v", fileTag.FileId, fileTag.TagId, fileTag.ValueId)
				}
			}
		}
	}

	return nil
}
Example #2
0
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
}