mfer/mfer/manifest.go

115 lines
2.2 KiB
Go

package mfer
import (
"fmt"
"io"
"io/fs"
"os"
"path/filepath"
"strings"
"github.com/spf13/afero"
)
type ManifestFile struct {
Path string
FileInfo fs.FileInfo
}
func (m *ManifestFile) String() string {
return fmt.Sprintf("<File \"%s\">", m.Path)
}
type Manifest struct {
SourceFS afero.Fs
SourceFSRoot string
Files []*ManifestFile
ScanOptions *ManifestScanOptions
TotalFileSize int64
}
func (m *Manifest) String() string {
return fmt.Sprintf("<Manifest count=%d totalSize=%d>", len(m.Files), m.TotalFileSize)
}
type ManifestScanOptions struct {
IgnoreDotfiles bool
FollowSymLinks bool
}
func NewFromPath(inputPath string, options *ManifestScanOptions) (*Manifest, error) {
abs, err := filepath.Abs(inputPath)
if err != nil {
return nil, err
}
afs := afero.NewBasePathFs(afero.NewOsFs(), abs)
m, err := NewFromFS(afs, options)
if err != nil {
return nil, err
}
m.SourceFSRoot = abs
return m, nil
}
func NewFromFS(fs afero.Fs, options *ManifestScanOptions) (*Manifest, error) {
m := &Manifest{
SourceFS: fs,
ScanOptions: options,
}
err := m.Scan()
if err != nil {
return nil, err
}
return m, nil
}
func (m *Manifest) Scan() error {
// FIXME scan and whatever function does the hashing should take ctx
oe := afero.Walk(m.SourceFS, "./", func(path string, info fs.FileInfo, err error) error {
if m.ScanOptions.IgnoreDotfiles && strings.HasPrefix(path, ".") {
// FIXME make this check all path components BUG
return nil
}
if info != nil && info.IsDir() {
// manifests contain only files, directories are implied.
return nil
}
fileinfo, staterr := m.SourceFS.Stat(path)
if staterr != nil {
panic(staterr)
}
nf := &ManifestFile{
Path: path,
FileInfo: fileinfo,
}
m.Files = append(m.Files, nf)
m.TotalFileSize = m.TotalFileSize + info.Size()
return nil
})
if oe != nil {
return oe
}
return nil
}
func (m *Manifest) WriteToFile(path string) error {
// FIXME refuse to overwrite without -f if file exists
f, err := os.Create(path)
if err != nil {
return err
}
defer f.Close()
return m.Write(f)
}
func (m *Manifest) Write(output io.Writer) error {
// FIXME implement
panic("nope")
return nil // nolint:all
}