feat(sync): add .ignore file to filter folder's content

This commit is contained in:
DataHearth 2022-06-01 19:22:27 +02:00
parent 81713eb583
commit 3b3a4d59e0
No known key found for this signature in database
GPG Key ID: E88FD356ACC5F3C4
3 changed files with 149 additions and 71 deletions

View File

@ -10,13 +10,13 @@ import (
)
type Configuration struct {
Storage Storage `mapstructure:"storage" yaml:"storage"`
Files []ItemLocation `mapstructure:"files" yaml:"files"`
Folders []ItemLocation `mapstructure:"folders" yaml:"folders"`
PackageManagers PkgManagers `mapstructure:"package-managers" yaml:"package-managers"`
Storage Storage `mapstructure:"storage" yaml:"storage"`
Files []OSLocation `mapstructure:"files" yaml:"files"`
Folders []OSLocation `mapstructure:"folders" yaml:"folders"`
PackageManagers PkgManagers `mapstructure:"package-managers" yaml:"package-managers"`
}
type ItemLocation struct {
type OSLocation struct {
Darwin string `mapstructure:"darwin" yaml:"darwin"`
Linux string `mapstructure:"linux" yaml:"linux"`
}

View File

@ -12,7 +12,7 @@ import (
)
type Items struct {
locations []ItemLocation
locations []OSLocation
storage string
repository RepositoryActions
indexer Indexer
@ -20,13 +20,13 @@ type Items struct {
type ItemsActions interface {
Action(action string)
AddItems(items []ItemLocation)
AddItems(items []OSLocation)
CleanUp(removedLines []string) error
}
func NewItemsActions(items []ItemLocation, storage string, repository RepositoryActions, indexer Indexer) ItemsActions {
func NewItemsActions(items []OSLocation, storage string, repository RepositoryActions, indexer Indexer) ItemsActions {
if items == nil {
items = []ItemLocation{}
items = []OSLocation{}
}
return &Items{
@ -37,79 +37,35 @@ func NewItemsActions(items []ItemLocation, storage string, repository Repository
}
}
func (e *Items) Action(a string) {
color.Blue("# %s", a)
func (e *Items) Action(action string) {
color.Blue("# %s", action)
newLines := []string{}
for i, l := range e.locations {
var src, dst string
var src 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" {
if action == "save" {
src = systemPath
dst = storagePath
if newItem := e.saveItem(systemPath, storagePath, i); newItem != "" {
newLines = append(newLines, newItem)
} else {
continue
}
} 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+"/", ""))
e.loadItem(storagePath, systemPath, i)
}
color.Green("[%d] %s copied", i, src)
}
if a == "save" && !viper.GetBool("disable-index-update") {
if action == "save" && !viper.GetBool("disable-index-update") {
if err := e.indexer.Write(newLines); err != nil {
PrintError(err.Error())
os.Exit(1)
@ -117,7 +73,99 @@ func (e *Items) Action(a string) {
}
}
func (e *Items) AddItems(items []ItemLocation) {
func (e *Items) saveItem(src, dst string, index int) string {
if err := os.MkdirAll(path.Dir(dst), 0755); err != nil {
PrintError("[%d] failed to create directory architecture for destination path \"%s\": %v", index, path.Dir(dst), err)
return ""
}
s, err := os.Stat(src)
if err != nil {
PrintError("[%d] failed to check if source path is a folder \"%s\": %v", index, src, err)
return ""
}
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", index, dst, err)
return ""
}
} 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", index, dst, err)
return ""
}
}
if err := copyFolder(src, dst, true); err != nil {
PrintError("[%d] failed to save folder from \"%s\" to \"%s\": %v", index, src, dst, err)
return ""
}
} else {
if err := copyFile(src, dst); err != nil {
PrintError("[%d] failed to save file from \"%s\" to \"%s\": %v", index, src, dst, err)
return ""
}
}
p, err := absolutePath(e.storage)
if err != nil {
PrintError("[%d] failed resolve absolute path from configuration storage: %v", index, err)
return ""
}
return strings.ReplaceAll(dst, p+"/", "")
}
func (e *Items) loadItem(src, dst string, index int) {
if err := os.MkdirAll(path.Dir(dst), 0755); err != nil {
PrintError("[%d] failed to create directory architecture for destination path \"%s\": %v", index, path.Dir(dst), err)
return
}
s, err := os.Stat(src)
if err != nil {
PrintError("[%d] failed to check if source path is a folder \"%s\": %v", index, src, err)
return
}
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", index, dst, err)
return
}
} 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", index, dst, err)
return
}
}
if err := copyFolder(src, dst, false); err != nil {
PrintError("[%d] failed to load folder from \"%s\" to \"%s\": %v", index, src, dst, err)
return
}
} else {
if err := copyFile(src, dst); err != nil {
PrintError("[%d] failed to load file from \"%s\" to \"%s\": %v", index, src, dst, err)
return
}
}
}
func (e *Items) AddItems(items []OSLocation) {
e.locations = append(e.locations, items...)
}

View File

@ -4,6 +4,7 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"os"
"path"
"runtime"
@ -44,6 +45,10 @@ func absolutePath(p string) (string, error) {
func getPaths(p string, l string) (string, string, error) {
paths := strings.Split(p, ":")
if len(paths) < 2 {
return "", "", errors.New("path incorrectly formatted. It requires \"source:destination\"")
}
src, err := absolutePath(strings.Replace(paths[0], "$LOCATION", l, 1))
if err != nil {
return "", "", err
@ -86,18 +91,18 @@ func copyFile(src, dst string) error {
return nil
}
func configPaths(f ItemLocation, location string) (string, string, error) {
func configPaths(os OSLocation, location string) (string, string, error) {
var src, dst string
var err error
switch runtime.GOOS {
case "linux":
src, dst, err = getPaths(f.Linux, location)
src, dst, err = getPaths(os.Linux, location)
if err != nil {
return "", "", err
}
case "darwin":
src, dst, err = getPaths(f.Darwin, location)
src, dst, err = getPaths(os.Darwin, location)
if err != nil {
return "", "", err
}
@ -108,15 +113,40 @@ func configPaths(f ItemLocation, location string) (string, string, error) {
return src, dst, nil
}
func copyFolder(src, dst string) error {
var ignored map[string]bool
func copyFolder(src, dst string, checkIgnore bool) error {
items, err := os.ReadDir(src)
if err != nil {
return err
}
if checkIgnore {
f, err := ioutil.ReadFile(fmt.Sprintf("%s/.ignore", src))
if err != nil && !errors.Is(err, io.EOF) {
if !errors.Is(err, os.ErrNotExist) {
return err
}
}
ignored = map[string]bool{}
for _, l := range strings.Split(string(f), "\n") {
if l != "" && !strings.Contains(l, "#") {
ignored[fmt.Sprintf("%s/%s", src, l)] = true
}
}
}
for _, i := range items {
itemName := i.Name()
srcItem := fmt.Sprintf("%s/%s", src, itemName)
// do not copy item if it's present in .ignore file
if ignored != nil {
if _, ok := ignored[srcItem]; ok {
continue
}
}
dstItem := fmt.Sprintf("%s/%s", dst, itemName)
if i.IsDir() {
@ -128,7 +158,7 @@ func copyFolder(src, dst string) error {
if err := os.MkdirAll(dstItem, info.Mode()); err != nil {
return err
}
if err := copyFolder(srcItem, dstItem); err != nil {
if err := copyFolder(srcItem, dstItem, false); err != nil {
return err
}