1package fsutil
2
3import (
4	"os"
5
6	"github.com/pkg/errors"
7)
8
9// Hardlinks validates that all targets for links were part of the changes
10
11type Hardlinks struct {
12	seenFiles map[string]struct{}
13}
14
15func (v *Hardlinks) HandleChange(kind ChangeKind, p string, fi os.FileInfo, err error) error {
16	if err != nil {
17		return err
18	}
19
20	if v.seenFiles == nil {
21		v.seenFiles = make(map[string]struct{})
22	}
23
24	if kind == ChangeKindDelete {
25		return nil
26	}
27
28	stat, ok := fi.Sys().(*Stat)
29	if !ok {
30		return errors.Errorf("invalid change without stat info: %s", p)
31	}
32
33	if fi.IsDir() || fi.Mode()&os.ModeSymlink != 0 {
34		return nil
35	}
36
37	if len(stat.Linkname) > 0 {
38		if _, ok := v.seenFiles[stat.Linkname]; !ok {
39			return errors.Errorf("invalid link %s to unknown path: %q", p, stat.Linkname)
40		}
41	} else {
42		v.seenFiles[p] = struct{}{}
43	}
44
45	return nil
46}
47