Files
postmarketos-mkinitfs/internal/filelist/filelist.go
2023-04-18 17:53:37 +01:00

92 lines
1.7 KiB
Go

package filelist
import (
"fmt"
"path/filepath"
"sync"
"gitlab.com/postmarketOS/postmarketos-mkinitfs/internal/misc"
)
type FileLister interface {
List() (*FileList, error)
}
type File struct {
Source string
Dest string
}
type FileList struct {
m map[string]string
sync.RWMutex
}
func NewFileList() *FileList {
return &FileList{
m: make(map[string]string),
}
}
func (f *FileList) Add(src string, dest string) {
f.Lock()
defer f.Unlock()
f.m[src] = dest
}
func (f *FileList) Get(src string) (string, bool) {
f.RLock()
defer f.RUnlock()
dest, found := f.m[src]
return dest, found
}
// Import copies in the contents of src. If a source path already exists when
// importing, then the destination path is updated with the new value.
func (f *FileList) Import(src *FileList) {
for i := range src.IterItems() {
f.Add(i.Source, i.Dest)
}
}
func (f *FileList) AddGlobbed(src string, dest string) error {
fFiles, err := misc.GetFiles([]string{src}, true)
if err != nil {
return fmt.Errorf("unable to add %q: %w", src, err)
}
// loop over all returned files from GetFile
for _, file := range fFiles {
if len(fFiles) > 1 {
// Glob with arbitrary subdirectories, so we need to
// remove the src path and prepend the dest path
f.Add(file, filepath.Join(dest, file[len(src):]))
} else {
// dest path specified, and only 1 file
f.Add(file, dest)
}
}
return nil
}
// iterate through the list and and send each one as a new File over the
// returned channel
func (f *FileList) IterItems() <-chan File {
ch := make(chan File)
go func() {
f.RLock()
defer f.RUnlock()
for src, dest := range f.m {
ch <- File{
Source: src,
Dest: dest,
}
}
close(ch)
}()
return ch
}