From 310216f7db2111ab889adc846d070dfd0e0866a1 Mon Sep 17 00:00:00 2001 From: Zhijie Yang Date: Thu, 28 Nov 2024 12:32:42 +0100 Subject: [PATCH] feat: use LinkType to identify hard links for report.Add --- internal/fsutil/create.go | 32 ++++++++++++++++++++++---------- internal/manifest/report.go | 12 ++---------- 2 files changed, 24 insertions(+), 20 deletions(-) diff --git a/internal/fsutil/create.go b/internal/fsutil/create.go index 6b54e524..9d2f9b9f 100644 --- a/internal/fsutil/create.go +++ b/internal/fsutil/create.go @@ -26,12 +26,20 @@ type CreateOptions struct { OverrideMode bool } +// The following constants are used to distinguish different link types, +// such as hard links and symlinks. +const ( + TypeSymlink = 1 << iota + TypeHardLink +) + type Entry struct { - Path string - Mode fs.FileMode - SHA256 string - Size int - Link string + Path string + Mode fs.FileMode + SHA256 string + Size int + Link string + LinkType int } // Create creates a filesystem entry according to the provided options and returns @@ -45,6 +53,7 @@ func Create(options *CreateOptions) (*Entry, error) { var err error var hash string + var linkType int if o.MakeParents { if err := os.MkdirAll(filepath.Dir(o.Path), 0755); err != nil { return nil, err @@ -57,6 +66,7 @@ func Create(options *CreateOptions) (*Entry, error) { // Creating the hard link does not involve reading the file. // Therefore, its size and hash is not calculated here. err = createHardLink(o) + linkType = TypeHardLink } else { err = createFile(o) hash = hex.EncodeToString(rp.h.Sum(nil)) @@ -65,6 +75,7 @@ func Create(options *CreateOptions) (*Entry, error) { err = createDir(o) case fs.ModeSymlink: err = createSymlink(o) + linkType = TypeSymlink default: err = fmt.Errorf("unsupported file type: %s", o.Path) } @@ -87,11 +98,12 @@ func Create(options *CreateOptions) (*Entry, error) { } entry := &Entry{ - Path: o.Path, - Mode: mode, - SHA256: hash, - Size: rp.size, - Link: o.Link, + Path: o.Path, + Mode: mode, + SHA256: hash, + Size: rp.size, + Link: o.Link, + LinkType: linkType, } return entry, nil } diff --git a/internal/manifest/report.go b/internal/manifest/report.go index 9814b7f9..1972e48e 100644 --- a/internal/manifest/report.go +++ b/internal/manifest/report.go @@ -61,7 +61,7 @@ func (r *Report) Add(slice *setup.Slice, fsEntry *fsutil.Entry) error { } hardLinkId := NON_HARD_LINK - if r.entryIsHardLink(fsEntry.Link) { + if fsEntry.LinkType == fsutil.TypeHardLink { hardLinkId = r.getHardLinkId(fsEntry) } @@ -110,6 +110,7 @@ func (r *Report) getHardLinkId(fsEntry *fsutil.Entry) uint64 { fsEntry.Link = "" } else { // The hard link links to a symlink + fmt.Println("FSENTRY:", fsEntry.Path, fsEntry.Link, "ENTRY:", entry.Path, entry.Link) fsEntry.Link = entry.Link } } @@ -151,12 +152,3 @@ func (r *Report) sanitizeAbsPath(path string, isDir bool) (relPath string, err e } return relPath, nil } - -// entryIsHardLink determines if a link is a hard link by checking if the link -// has a prefix of the root dir, since hard links are created with absolute -// paths prefixing the report's root dir, while symlinks are created either with -// relative paths or absolute paths that do not have the report's root dir as a -// prefix. -func (r *Report) entryIsHardLink(link string) bool { - return link != "" && strings.HasPrefix(link, r.Root) -}