Skip to content

Commit

Permalink
chore: refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
zhijie-yang committed Nov 27, 2024
1 parent 5806b0b commit b0f4271
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 40 deletions.
45 changes: 29 additions & 16 deletions internal/deb/extract.go
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,14 @@ func extractData(pkgReader io.ReadSeeker, options *ExtractOptions) error {
return err
}
tarReader := tar.NewReader(dataReader)
err = handlePendingHardLinks(options, pendingHardLinks, tarReader, pendingPaths)
extractHardLinkOptions := &extractHardLinkOptions{
extractOptions: options,
links: pendingHardLinks,
tarReader: tarReader,
pendingPaths: pendingPaths,
}

err = handlePendingHardLinks(extractHardLinkOptions)
if err != nil {
return err
}
Expand All @@ -336,10 +343,16 @@ func extractData(pkgReader io.ReadSeeker, options *ExtractOptions) error {
return nil
}

func handlePendingHardLinks(options *ExtractOptions, pendingHardLinks map[string][]HardLinkInfo,
tarReader *tar.Reader, pendingPaths map[string]bool) error {
type extractHardLinkOptions struct {
extractOptions *ExtractOptions
links map[string][]HardLinkInfo
tarReader *tar.Reader
pendingPaths map[string]bool
}

func handlePendingHardLinks(opts *extractHardLinkOptions) error {
for {
tarHeader, err := tarReader.Next()
tarHeader, err := opts.tarReader.Next()
if err == io.EOF {
break
}
Expand All @@ -352,43 +365,43 @@ func handlePendingHardLinks(options *ExtractOptions, pendingHardLinks map[string
continue
}

hardLinks, ok := pendingHardLinks[sourcePath]
if !ok || len(hardLinks) == 0 {
links, ok := opts.links[sourcePath]
if !ok || len(links) == 0 {
continue
}

// Since the hard link target file was not extracted in the first pass,
// we extract the first hard link as a regular file. For the rest of
// the hard link entries, we link those paths to first file extracted.
targetPath := hardLinks[0].TargetPath
extractPath := filepath.Join(options.TargetDir, targetPath)
targetPath := links[0].TargetPath
extractPath := filepath.Join(opts.extractOptions.TargetDir, targetPath)
// Write the content for the first file in the hard link group
createOptions := &fsutil.CreateOptions{
Path: extractPath,
Mode: tarHeader.FileInfo().Mode(),
Data: tarReader,
Data: opts.tarReader,
}

err = options.Create(hardLinks[0].ExtractInfos, createOptions)
err = opts.extractOptions.Create(links[0].ExtractInfos, createOptions)
if err != nil {
return err
}
delete(pendingPaths, sourcePath)
delete(pendingPaths, targetPath)
delete(opts.pendingPaths, sourcePath)
delete(opts.pendingPaths, targetPath)

// Create the remaining hard links.
for _, hardLink := range hardLinks[1:] {
for _, link := range links[1:] {
createOptions := &fsutil.CreateOptions{
Path: filepath.Join(options.TargetDir, hardLink.TargetPath),
Path: filepath.Join(opts.extractOptions.TargetDir, link.TargetPath),
Mode: tarHeader.FileInfo().Mode(),
// Link to the first file extracted for the hard links.
Link: extractPath,
}
err := options.Create(hardLink.ExtractInfos, createOptions)
err := opts.extractOptions.Create(link.ExtractInfos, createOptions)
if err != nil {
return err
}
delete(pendingPaths, hardLink.TargetPath)
delete(opts.pendingPaths, link.TargetPath)
}
}
return nil
Expand Down
48 changes: 24 additions & 24 deletions internal/fsutil/create_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ import (
type createTest struct {
summary string
options fsutil.CreateOptions
hackopt func(c *C, targetDir string, options *fsutil.CreateOptions)
hackopt func(c *C, dir string, opts *fsutil.CreateOptions)
result map[string]string
error string
}
Expand Down Expand Up @@ -79,8 +79,8 @@ var createTests = []createTest{{
Path: "foo",
Mode: fs.ModeDir | 0775,
},
hackopt: func(c *C, targetDir string, options *fsutil.CreateOptions) {
c.Assert(os.Mkdir(filepath.Join(targetDir, "foo/"), fs.ModeDir|0765), IsNil)
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
c.Assert(os.Mkdir(filepath.Join(dir, "foo/"), fs.ModeDir|0765), IsNil)
},
result: map[string]string{
// mode is not updated.
Expand All @@ -94,8 +94,8 @@ var createTests = []createTest{{
Mode: 0644,
Data: bytes.NewBufferString("changed"),
},
hackopt: func(c *C, targetDir string, options *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(targetDir, "foo"), []byte("data"), 0666), IsNil)
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(dir, "foo"), []byte("data"), 0666), IsNil)
},
result: map[string]string{
// mode is not updated.
Expand All @@ -109,10 +109,10 @@ var createTests = []createTest{{
Mode: 0644,
MakeParents: true,
},
hackopt: func(c *C, targetDir string, options *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(targetDir, "file"), []byte("data"), 0644), IsNil)
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(dir, "file"), []byte("data"), 0644), IsNil)
// An absolute path is required to create a hard link.
options.Link = filepath.Join(targetDir, options.Link)
opts.Link = filepath.Join(dir, opts.Link)
},
result: map[string]string{
"/file": "file 0644 3a6eb079",
Expand All @@ -126,8 +126,8 @@ var createTests = []createTest{{
Mode: 0644,
MakeParents: true,
},
hackopt: func(c *C, targetDir string, options *fsutil.CreateOptions) {
options.Link = filepath.Join(targetDir, options.Link)
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
opts.Link = filepath.Join(dir, opts.Link)
},
error: `link target does not exist`,
}, {
Expand All @@ -138,10 +138,10 @@ var createTests = []createTest{{
Mode: 0644,
MakeParents: true,
},
hackopt: func(c *C, targetDir string, options *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(targetDir, "file"), []byte("data"), 0644), IsNil)
c.Assert(os.Link(filepath.Join(targetDir, "file"), filepath.Join(targetDir, "hardlink")), IsNil)
options.Link = filepath.Join(targetDir, options.Link)
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(dir, "file"), []byte("data"), 0644), IsNil)
c.Assert(os.Link(filepath.Join(dir, "file"), filepath.Join(dir, "hardlink")), IsNil)
opts.Link = filepath.Join(dir, opts.Link)
},
result: map[string]string{
"/file": "file 0644 3a6eb079",
Expand All @@ -155,10 +155,10 @@ var createTests = []createTest{{
Mode: 0644,
MakeParents: true,
},
hackopt: func(c *C, targetDir string, options *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(targetDir, "file"), []byte("data"), 0644), IsNil)
c.Assert(os.WriteFile(filepath.Join(targetDir, "hardlink"), []byte("data"), 0644), IsNil)
options.Link = filepath.Join(targetDir, options.Link)
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
c.Assert(os.WriteFile(filepath.Join(dir, "file"), []byte("data"), 0644), IsNil)
c.Assert(os.WriteFile(filepath.Join(dir, "hardlink"), []byte("data"), 0644), IsNil)
opts.Link = filepath.Join(dir, opts.Link)
},
error: `path \/[^ ]*\/hardlink already exists`,
}, {
Expand All @@ -167,7 +167,7 @@ var createTests = []createTest{{
Mode: fs.ModeDir | 0775,
OverrideMode: true,
},
hackopt: func(c *C, dir string, options *fsutil.CreateOptions) {
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
c.Assert(os.Mkdir(filepath.Join(dir, "foo/"), fs.ModeDir|0765), IsNil)
},
result: map[string]string{
Expand All @@ -181,7 +181,7 @@ var createTests = []createTest{{
Data: bytes.NewBufferString("whatever"),
OverrideMode: true,
},
hackopt: func(c *C, dir string, options *fsutil.CreateOptions) {
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
err := os.WriteFile(filepath.Join(dir, "foo"), []byte("data"), 0666)
c.Assert(err, IsNil)
},
Expand All @@ -195,7 +195,7 @@ var createTests = []createTest{{
Link: "./bar",
Mode: 0666 | fs.ModeSymlink,
},
hackopt: func(c *C, dir string, options *fsutil.CreateOptions) {
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
err := os.WriteFile(filepath.Join(dir, "foo"), []byte("data"), 0666)
c.Assert(err, IsNil)
},
Expand All @@ -209,7 +209,7 @@ var createTests = []createTest{{
Mode: 0776 | fs.ModeSymlink,
OverrideMode: true,
},
hackopt: func(c *C, dir string, options *fsutil.CreateOptions) {
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
err := os.WriteFile(filepath.Join(dir, "bar"), []byte("data"), 0666)
c.Assert(err, IsNil)
err = os.WriteFile(filepath.Join(dir, "foo"), []byte("data"), 0666)
Expand All @@ -227,7 +227,7 @@ var createTests = []createTest{{
Link: "other",
Mode: 0666 | fs.ModeSymlink,
},
hackopt: func(c *C, dir string, options *fsutil.CreateOptions) {
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
err := os.Symlink("foo", filepath.Join(dir, "bar"))
c.Assert(err, IsNil)
},
Expand All @@ -241,7 +241,7 @@ var createTests = []createTest{{
Link: "foo",
Mode: 0666 | fs.ModeSymlink,
},
hackopt: func(c *C, dir string, options *fsutil.CreateOptions) {
hackopt: func(c *C, dir string, opts *fsutil.CreateOptions) {
err := os.Symlink("foo", filepath.Join(dir, "bar"))
c.Assert(err, IsNil)
},
Expand Down

0 comments on commit b0f4271

Please sign in to comment.