138 lines
3.0 KiB
Go
138 lines
3.0 KiB
Go
package mapper
|
|
|
|
import (
|
|
"fmt"
|
|
"io/fs"
|
|
"os"
|
|
"path"
|
|
"strings"
|
|
|
|
"github.com/fatih/color"
|
|
"github.com/spf13/viper"
|
|
)
|
|
|
|
type Items struct {
|
|
locations []ItemLocation
|
|
storage string
|
|
repository RepositoryActions
|
|
indexer Indexer
|
|
}
|
|
|
|
type ItemsActions interface {
|
|
Action(action string)
|
|
AddItems(items []ItemLocation)
|
|
CleanUp(removedLines []string) error
|
|
}
|
|
|
|
func NewItemsActions(items []ItemLocation, storage string, repository RepositoryActions, indexer Indexer) ItemsActions {
|
|
if items == nil {
|
|
items = []ItemLocation{}
|
|
}
|
|
|
|
return &Items{
|
|
locations: items,
|
|
storage: storage,
|
|
repository: repository,
|
|
indexer: indexer,
|
|
}
|
|
}
|
|
|
|
func (e *Items) Action(a string) {
|
|
color.Blue("# %s", a)
|
|
newLines := []string{}
|
|
|
|
for i, l := range e.locations {
|
|
var src, dst string
|
|
storagePath, systemPath, err := configPaths(l, e.storage)
|
|
if err != nil {
|
|
PrintError("[%d] failed to resolve item paths \"%v\": %v", i, l, err)
|
|
continue
|
|
}
|
|
|
|
if a == "save" {
|
|
src = systemPath
|
|
dst = storagePath
|
|
} else {
|
|
src = storagePath
|
|
dst = systemPath
|
|
}
|
|
|
|
if err := os.MkdirAll(path.Dir(dst), 0755); err != nil {
|
|
PrintError("[%d] failed to create directory architecture for destination path \"%s\": %v", i, path.Dir(dst), err)
|
|
continue
|
|
}
|
|
|
|
s, err := os.Stat(src)
|
|
if err != nil {
|
|
PrintError("[%d] failed to check if source path is a folder \"%s\": %v", i, src, err)
|
|
continue
|
|
}
|
|
|
|
if s.IsDir() {
|
|
dstPerms := fs.FileMode(0755)
|
|
s, err := os.Stat(dst)
|
|
if err != nil {
|
|
if !os.IsNotExist(err) {
|
|
PrintError("[%d] failed to check if destination folder \"%s\" exists: %v", i, dst, err)
|
|
continue
|
|
}
|
|
} else {
|
|
dstPerms = s.Mode()
|
|
}
|
|
|
|
if err := os.Mkdir(dst, dstPerms); err != nil {
|
|
if !os.IsExist(err) {
|
|
PrintError("[%d] failed to create destination folder \"%s\": %v", i, dst, err)
|
|
continue
|
|
}
|
|
}
|
|
if err := copyFolder(src, dst); err != nil {
|
|
PrintError("[%d] failed to %s folder from \"%s\" to \"%s\": %v", i, a, src, dst, err)
|
|
continue
|
|
}
|
|
} else {
|
|
if err := copyFile(src, dst); err != nil {
|
|
PrintError("[%d] failed to %s file from \"%s\" to \"%s\": %v", i, a, src, dst, err)
|
|
continue
|
|
}
|
|
}
|
|
|
|
if a == "save" {
|
|
p, err := absolutePath(e.storage)
|
|
if err != nil {
|
|
PrintError("[%d] failed resolve absolute path from configuration storage: %v", i, err)
|
|
continue
|
|
}
|
|
newLines = append(newLines, strings.ReplaceAll(dst, p+"/", ""))
|
|
}
|
|
|
|
color.Green("[%d] %s copied", i, src)
|
|
}
|
|
|
|
if a == "save" && !viper.GetBool("disable-index-update") {
|
|
if err := e.indexer.Write(newLines); err != nil {
|
|
PrintError(err.Error())
|
|
os.Exit(1)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (e *Items) AddItems(items []ItemLocation) {
|
|
e.locations = append(e.locations, items...)
|
|
}
|
|
|
|
func (e *Items) CleanUp(removedLines []string) error {
|
|
for _, l := range removedLines {
|
|
path, err := absolutePath(fmt.Sprintf("%s/%s", e.storage, l))
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
if err := os.RemoveAll(path); err != nil {
|
|
return fmt.Errorf("failed to remove item %s: %v", l, err)
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}
|