-
Notifications
You must be signed in to change notification settings - Fork 358
/
extractor.go
82 lines (61 loc) · 1.85 KB
/
extractor.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
package lockfile
import (
"errors"
"io"
"os"
"path/filepath"
)
var ErrOpenNotSupported = errors.New("this file does not support opening files")
// DepFile is an abstraction for a file that has been opened for extraction,
// and that knows how to open other DepFiles relative to itself.
type DepFile interface {
io.Reader
// Open opens an NestedDepFile based on the path of the
// current DepFile if the provided path is relative.
//
// If the path is an absolute path, then it is opened absolutely.
Open(path string) (NestedDepFile, error)
Path() string
}
// NestedDepFile is an abstraction for a file that has been opened while extracting another file,
// and would need to be closed.
type NestedDepFile interface {
io.Closer
DepFile
}
type Extractor interface {
// ShouldExtract checks if the Extractor should be used for the given path.
ShouldExtract(path string) bool
Extract(f DepFile) ([]PackageDetails, error)
}
// A LocalFile represents a file that exists on the local filesystem.
type LocalFile struct {
io.ReadCloser
path string
}
func (f LocalFile) Open(path string) (NestedDepFile, error) {
if filepath.IsAbs(path) {
return OpenLocalDepFile(path)
}
return OpenLocalDepFile(filepath.Join(filepath.Dir(f.path), path))
}
func (f LocalFile) Path() string { return f.path }
func OpenLocalDepFile(path string) (NestedDepFile, error) {
r, err := os.Open(path)
if err != nil {
return LocalFile{}, err
}
// Very unlikely to have Abs return an error if the file opens correctly
path, _ = filepath.Abs(path)
return LocalFile{r, path}, nil
}
var _ DepFile = LocalFile{}
var _ NestedDepFile = LocalFile{}
func extractFromFile(pathToLockfile string, extractor Extractor) ([]PackageDetails, error) {
f, err := OpenLocalDepFile(pathToLockfile)
if err != nil {
return []PackageDetails{}, err
}
defer f.Close()
return extractor.Extract(f)
}