Skip to content

Commit 685dc25

Browse files
authored
Merge pull request #28 from cmaglie/prepare-v4
Add Remove to FS interface. Prepare for release v4.
2 parents 3554ee1 + 0b34435 commit 685dc25

7 files changed

Lines changed: 75 additions & 52 deletions

File tree

README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
[![GitHub license](https://img.shields.io/badge/license-MIT-blue.svg)](https://raw.githubusercontent.com/codeclysm/extract/master/LICENSE)
55
[![Godoc Reference](https://img.shields.io/badge/Godoc-Reference-blue.svg)](https://godoc.org/github.com/codeclysm/extract)
66

7-
import "github.com/codeclysm/extract/v3"
7+
import "github.com/codeclysm/extract/v4"
88

99
Package extract allows to extract archives in zip, tar.gz or tar.bz2 formats
1010
easily.
@@ -54,6 +54,7 @@ type FS interface {
5454
MkdirAll(string, os.FileMode) error
5555
OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
5656
Symlink(string, string) error
57+
Remove(path string) error
5758
}
5859
```
5960

extract.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,6 @@ func Zip(ctx context.Context, body io.Reader, location string, rename Renamer) e
9292
type fs struct{}
9393

9494
func (f fs) Link(oldname, newname string) error {
95-
_ = os.Remove(newname) // Ignore error. We don't care if the file doesn't exist.
9695
return os.Link(oldname, newname)
9796
}
9897

@@ -101,10 +100,13 @@ func (f fs) MkdirAll(path string, perm os.FileMode) error {
101100
}
102101

103102
func (f fs) Symlink(oldname, newname string) error {
104-
_ = os.Remove(newname) // Ignore error. We don't care if the file doesn't exist.
105103
return os.Symlink(oldname, newname)
106104
}
107105

108106
func (f fs) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
109107
return os.OpenFile(name, flag, perm)
110108
}
109+
110+
func (f fs) Remove(path string) error {
111+
return os.Remove(path)
112+
}

extract_test.go

Lines changed: 40 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import (
1414
"testing"
1515

1616
"github.com/arduino/go-paths-helper"
17-
"github.com/codeclysm/extract/v3"
17+
"github.com/codeclysm/extract/v4"
1818
"github.com/stretchr/testify/require"
1919
)
2020

@@ -222,43 +222,45 @@ func TestExtract(t *testing.T) {
222222

223223
func TestExtractIdempotency(t *testing.T) {
224224
for _, test := range ExtractCases {
225-
dir, _ := os.MkdirTemp("", "")
226-
dir = filepath.Join(dir, "test")
227-
data, err := os.ReadFile(test.Archive)
228-
if err != nil {
229-
t.Fatal(err)
230-
}
231-
232-
var extractFn func(context.Context, io.Reader, string, extract.Renamer) error
233-
switch filepath.Ext(test.Archive) {
234-
case ".bz2":
235-
extractFn = extract.Bz2
236-
case ".gz":
237-
extractFn = extract.Gz
238-
case ".zip":
239-
extractFn = extract.Zip
240-
case ".mistery":
241-
extractFn = extract.Archive
242-
default:
243-
t.Fatal("unknown error")
244-
}
245-
246-
buffer := bytes.NewBuffer(data)
247-
if err = extractFn(context.Background(), buffer, dir, test.Renamer); err != nil {
248-
t.Fatal(test.Name, ": Should not fail first extraction: "+err.Error())
249-
}
250-
251-
buffer = bytes.NewBuffer(data)
252-
if err = extractFn(context.Background(), buffer, dir, test.Renamer); err != nil {
253-
t.Fatal(test.Name, ": Should not fail second extraction: "+err.Error())
254-
}
255-
256-
testWalk(t, dir, test.Files)
257-
258-
err = os.RemoveAll(dir)
259-
if err != nil {
260-
t.Fatal(err)
261-
}
225+
t.Run(test.Name, func(t *testing.T) {
226+
dir, _ := os.MkdirTemp("", "")
227+
dir = filepath.Join(dir, "test")
228+
data, err := os.ReadFile(test.Archive)
229+
if err != nil {
230+
t.Fatal(err)
231+
}
232+
233+
var extractFn func(context.Context, io.Reader, string, extract.Renamer) error
234+
switch filepath.Ext(test.Archive) {
235+
case ".bz2":
236+
extractFn = extract.Bz2
237+
case ".gz":
238+
extractFn = extract.Gz
239+
case ".zip":
240+
extractFn = extract.Zip
241+
case ".mistery":
242+
extractFn = extract.Archive
243+
default:
244+
t.Fatal("unknown error")
245+
}
246+
247+
buffer := bytes.NewBuffer(data)
248+
if err = extractFn(context.Background(), buffer, dir, test.Renamer); err != nil {
249+
t.Fatal(test.Name, ": Should not fail first extraction: "+err.Error())
250+
}
251+
252+
buffer = bytes.NewBuffer(data)
253+
if err = extractFn(context.Background(), buffer, dir, test.Renamer); err != nil {
254+
t.Fatal(test.Name, ": Should not fail second extraction: "+err.Error())
255+
}
256+
257+
testWalk(t, dir, test.Files)
258+
259+
err = os.RemoveAll(dir)
260+
if err != nil {
261+
t.Fatal(err)
262+
}
263+
})
262264
}
263265
}
264266

extractor.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,6 @@ import (
2525
type Extractor struct {
2626
FS interface {
2727
// Link creates newname as a hard link to the oldname file. If there is an error, it will be of type *LinkError.
28-
// Differently from os.Link, if newname already exists it will be overwritten.
2928
Link(oldname, newname string) error
3029

3130
// MkdirAll creates the directory path and all his parents if needed.
@@ -35,8 +34,10 @@ type Extractor struct {
3534
OpenFile(name string, flag int, perm os.FileMode) (*os.File, error)
3635

3736
// Symlink creates newname as a symbolic link to oldname.
38-
// Differently from os.Symlink, if newname already exists it will be overwritten.
3937
Symlink(oldname, newname string) error
38+
39+
// Remove removes the named file or (empty) directory.
40+
Remove(path string) error
4041
}
4142
}
4243

@@ -230,6 +231,7 @@ func (e *Extractor) Tar(ctx context.Context, body io.Reader, location string, re
230231
return errors.New("interrupted")
231232
default:
232233
}
234+
_ = e.FS.Remove(links[i].Path)
233235
if err := e.FS.Link(links[i].Name, links[i].Path); err != nil {
234236
return errors.Annotatef(err, "Create link %s", links[i].Path)
235237
}
@@ -241,6 +243,7 @@ func (e *Extractor) Tar(ctx context.Context, body io.Reader, location string, re
241243
return errors.New("interrupted")
242244
default:
243245
}
246+
_ = e.FS.Remove(symlink.Path)
244247
if err := e.FS.Symlink(symlink.Name, symlink.Path); err != nil {
245248
return errors.Annotatef(err, "Create link %s", symlink.Path)
246249
}
@@ -344,6 +347,7 @@ func (e *Extractor) Zip(ctx context.Context, body io.Reader, location string, re
344347
return errors.New("interrupted")
345348
default:
346349
}
350+
_ = e.FS.Remove(link.Path)
347351
if err := e.FS.Symlink(link.Name, link.Path); err != nil {
348352
return errors.Annotatef(err, "Create link %s", link.Path)
349353
}
@@ -358,6 +362,7 @@ func (e *Extractor) copy(ctx context.Context, path string, mode os.FileMode, src
358362
if err != nil {
359363
return err
360364
}
365+
_ = e.FS.Remove(path)
361366
file, err := e.FS.OpenFile(path, os.O_CREATE|os.O_TRUNC|os.O_WRONLY, mode)
362367
if err != nil {
363368
return err

extractor_test.go

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ import (
1010
"testing"
1111

1212
"github.com/arduino/go-paths-helper"
13-
"github.com/codeclysm/extract/v3"
13+
"github.com/codeclysm/extract/v4"
1414
"github.com/stretchr/testify/require"
1515
)
1616

@@ -106,7 +106,6 @@ type MockDisk struct {
106106
func (m MockDisk) Link(oldname, newname string) error {
107107
oldname = filepath.Join(m.Base, oldname)
108108
newname = filepath.Join(m.Base, newname)
109-
_ = os.Remove(newname)
110109
return os.Link(oldname, newname)
111110
}
112111

@@ -118,11 +117,14 @@ func (m MockDisk) MkdirAll(path string, perm os.FileMode) error {
118117
func (m MockDisk) Symlink(oldname, newname string) error {
119118
oldname = filepath.Join(m.Base, oldname)
120119
newname = filepath.Join(m.Base, newname)
121-
_ = os.Remove(newname)
122120
return os.Symlink(oldname, newname)
123121
}
124122

125123
func (m MockDisk) OpenFile(name string, flag int, perm os.FileMode) (*os.File, error) {
126124
name = filepath.Join(m.Base, name)
127125
return os.OpenFile(name, flag, perm)
128126
}
127+
128+
func (m MockDisk) Remove(path string) error {
129+
return os.Remove(filepath.Join(m.Base, path))
130+
}

go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
module github.com/codeclysm/extract/v3
1+
module github.com/codeclysm/extract/v4
22

33
go 1.22
44

loggingfs_test.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,8 @@ func (op *LoggedOp) String() string {
2929
return fmt.Sprintf("mkdirall %v %s", op.Mode, op.Path)
3030
case "open":
3131
return fmt.Sprintf("open %v %s (flags=%04x)", op.Mode, op.Path, op.Flags)
32+
case "remove":
33+
return fmt.Sprintf("remove %v", op.Path)
3234
}
3335
panic("unknown LoggedOP " + op.Op)
3436
}
@@ -39,8 +41,7 @@ func (m *LoggingFS) Link(oldname, newname string) error {
3941
OldPath: oldname,
4042
Path: newname,
4143
})
42-
_ = os.Remove(newname)
43-
return nil
44+
return os.Link(oldname, newname)
4445
}
4546

4647
func (m *LoggingFS) MkdirAll(path string, perm os.FileMode) error {
@@ -49,7 +50,7 @@ func (m *LoggingFS) MkdirAll(path string, perm os.FileMode) error {
4950
Path: path,
5051
Mode: perm,
5152
})
52-
return nil
53+
return os.MkdirAll(path, perm)
5354
}
5455

5556
func (m *LoggingFS) Symlink(oldname, newname string) error {
@@ -58,8 +59,7 @@ func (m *LoggingFS) Symlink(oldname, newname string) error {
5859
OldPath: oldname,
5960
Path: newname,
6061
})
61-
_ = os.Remove(newname)
62-
return nil
62+
return os.Symlink(oldname, newname)
6363
}
6464

6565
func (m *LoggingFS) OpenFile(name string, flags int, perm os.FileMode) (*os.File, error) {
@@ -72,6 +72,17 @@ func (m *LoggingFS) OpenFile(name string, flags int, perm os.FileMode) (*os.File
7272
return os.OpenFile(os.DevNull, flags, perm)
7373
}
7474

75+
func (m *LoggingFS) Remove(path string) error {
76+
err := os.Remove(path)
77+
op := &LoggedOp{
78+
Op: "remove",
79+
Path: path,
80+
}
81+
m.Journal = append(m.Journal, op)
82+
fmt.Println("FS>", op)
83+
return err
84+
}
85+
7586
func (m *LoggingFS) String() string {
7687
res := ""
7788
for _, op := range m.Journal {

0 commit comments

Comments
 (0)