Skip to content

Commit

Permalink
refactoring
Browse files Browse the repository at this point in the history
  • Loading branch information
jankelemen committed Sep 12, 2021
1 parent b73b6db commit de9416a
Show file tree
Hide file tree
Showing 3 changed files with 66 additions and 64 deletions.
18 changes: 9 additions & 9 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,14 @@ import (
)

const (
MsgCanceling = "canceling"
MsgCalculating = "gathering info about files"
MgsAreYouSure = "Do you want to continue?"
MsgLogging = "Also a log file named 'log' will be generated."
MsgNothingToDo = "there is nothing to do"
MsgErrOccurred = "an error occurred"
MsgFinished = "the program finished successfully"
MsgDone = "done"
MsgCanceling = "canceling"
MsgGatheringInfo = "gathering info about files"
MgsAreYouSure = "Do you want to continue?"
MsgLogging = "Also a log file named 'log' will be generated."
MsgNothingToDo = "there is nothing to do"
MsgErrOccurred = "an error occurred:"
MsgFinished = "the program finished successfully"
MsgDone = "done"
)

func main() {
Expand Down Expand Up @@ -87,7 +87,7 @@ func doCleaning(dst, src string) {
}

func srcDstDiff(dst, src string, cleaningMod bool) (folders mirror.Folder, files mirror.File, totalSize int64) {
log.Println(MsgCalculating)
log.Println(MsgGatheringInfo)

srcFolders, srcFiles, err := mirror.ReadFolder(src)
checkErr(err)
Expand Down
65 changes: 37 additions & 28 deletions mirror/mirror.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@ package mirror
import (
"bufio"
"flag"
"fmt"
"io"
"log"
"os"
Expand All @@ -19,6 +18,7 @@ const (
ErrWrongArgs = CustomErr("wrong arguments, use the -h flag for help")
ErrSrcNotFound = CustomErr("source folder doesn't exist")
ErrDstNotFound = CustomErr("destination folder doesn't exist")
ErrOnlyFoldersOrFiles = CustomErr("the function accepts only folders and files")
FolderToIgnore = "dont_mirror"
LogFile = "log"
BytesInMB = 1e6
Expand Down Expand Up @@ -120,7 +120,6 @@ func readFolder(path string, startingPath string, folders Folder, files File) er
}

for _, item := range items {

currentName := item.Name()
currentPath := filepath.Join(path, currentName)
currentTrimmedPath, err := filepath.Rel(startingPath, currentPath)
Expand All @@ -140,7 +139,9 @@ func readFolder(path string, startingPath string, folders Folder, files File) er
if err != nil {
return err
}
files[currentTrimmedPath] = info.Size()
if info.Mode()&os.ModeSymlink != os.ModeSymlink {
files[currentTrimmedPath] = info.Size()
}
}
}
return nil
Expand Down Expand Up @@ -198,7 +199,7 @@ func FilesToClean(dst, src File) (res File, totalSize int64) {

// MakeFolders makes directories with os.MkdirAll in path directory and logs progress
func MakeFolders(folders Folder, path string) error {
var progressInPercentage, counter int
var recentlyLoggedProgress, counter int

f, err := initLogFile()
if err != nil {
Expand All @@ -207,12 +208,13 @@ func MakeFolders(folders Folder, path string) error {

LogToFile(f, LogMadeFolders+"\n")

for _, folder := range keepFoldersWithLongestPrefix(folders) {
sortedFolders := keepFoldersWithLongestPrefix(folders)
for _, folder := range sortedFolders {
if err = os.MkdirAll(filepath.Join(path, folder), FolderPerm); err != nil {
return err
}

logProgressFolders(&progressInPercentage, &counter, len(folders), fmt.Sprintf("%s %d%%", MsgProgressMakingFolders, progressInPercentage))
logProgressFolders(&recentlyLoggedProgress, &counter, len(sortedFolders), MsgProgressMakingFolders)

LogToFile(f, folder)
}
Expand All @@ -223,7 +225,7 @@ func MakeFolders(folders Folder, path string) error {

// CleanFolders removes directories with os.RemoveAll in path directory and logs progress
func CleanFolders(folders Folder, path string) error {
var progressInPercentage, counter int
var recentlyLoggedProgress, counter int

f, err := initLogFile()
if err != nil {
Expand All @@ -232,12 +234,13 @@ func CleanFolders(folders Folder, path string) error {

LogToFile(f, LogCleanedFolders+"\n")

for _, folder := range keepFoldersWithShortestPrefix(folders) {
sortedFolders := keepFoldersWithShortestPrefix(folders)
for _, folder := range sortedFolders {
if err = os.RemoveAll(filepath.Join(path, folder)); err != nil {
return err
}

logProgressFolders(&progressInPercentage, &counter, len(folders), fmt.Sprintf("%s %d%%", MsgProgressCleaningFolders, progressInPercentage))
logProgressFolders(&recentlyLoggedProgress, &counter, len(sortedFolders), MsgProgressCleaningFolders)

LogToFile(f, folder)
}
Expand All @@ -248,7 +251,7 @@ func CleanFolders(folders Folder, path string) error {

// CopyFiles copies files and logs progress. The 'files' parameter should contain relative paths
func CopyFiles(files File, totalSize int64, src, dst string) error {
var bytesWritten, progressInPercentage int64
var bytesWritten, recentlyLoggedProgress int64

l, err := initLogFile()
if err != nil {
Expand Down Expand Up @@ -281,7 +284,7 @@ func CopyFiles(files File, totalSize int64, src, dst string) error {
return err
}

logProgressFiles(&progressInPercentage, totalSize, bytesWritten, fmt.Sprintf("%s %d%%", MsgProgressCopyingFiles, progressInPercentage))
logProgressFiles(&recentlyLoggedProgress, totalSize, bytesWritten, MsgProgressCopyingFiles)

LogToFile(l, file)
}
Expand All @@ -295,7 +298,7 @@ func CopyFiles(files File, totalSize int64, src, dst string) error {

// CleanFiles removes files and logs progress. The 'files' parameter should contain relative paths
func CleanFiles(files File, totalSize int64, path string) error {
var bytesDeleted, progressInPercentage int64
var bytesDeleted, recentlyLoggedProgress int64

l, err := initLogFile()
if err != nil {
Expand All @@ -315,7 +318,7 @@ func CleanFiles(files File, totalSize int64, path string) error {
return err
}

logProgressFiles(&progressInPercentage, totalSize, bytesDeleted, fmt.Sprintf("%s %d%%", MsgProgressCleaningFiles, progressInPercentage))
logProgressFiles(&recentlyLoggedProgress, totalSize, bytesDeleted, MsgProgressCleaningFiles)

LogToFile(l, file)
}
Expand Down Expand Up @@ -364,24 +367,30 @@ func BytesToMB(size int64) string {
return ThousandSeparator(strconv.FormatInt(size/BytesInMB, 10))
}

func logProgressFiles(progressInPercentage *int64, totalSize, bytesWritten int64, msg string) {
// howOftenToLog is in percentage
var howOftenToLog int64 = 10
func logProgressFiles(recentlyLoggedProgress *int64, totalSize, bytesWritten int64, msg string) {
// howOftenToLog and progress are in percentage
var howOftenToLog, progress int64 = 10, 100

if totalSize > 0 {
progress = bytesWritten * 100 / totalSize
} else if totalSize == 0 && *recentlyLoggedProgress > 0 {
return
}

if totalSize > 0 && bytesWritten*100/totalSize > *progressInPercentage {
log.Println(msg)
*progressInPercentage += howOftenToLog
if progress > *recentlyLoggedProgress+howOftenToLog {
log.Printf("%s %d%%\n", msg, progress)
*recentlyLoggedProgress += progress
}
}

func logProgressFolders(progressInPercentage, counter *int, foldersLen int, msg string) {
// howOftenToLog is in percentage
howOftenToLog := 10
func logProgressFolders(recentlyLoggedProgress, counter *int, foldersLen int, msg string) {
*counter++
// howOftenToLog and progress are in percentage
var howOftenToLog, progress = 10, *counter * 100 / foldersLen

if *counter*100/foldersLen > *progressInPercentage {
log.Println(msg)
*progressInPercentage += howOftenToLog
if progress > *recentlyLoggedProgress+howOftenToLog {
log.Printf("%s %d%%\n", msg, progress)
*recentlyLoggedProgress += progress
}
return
}
Expand All @@ -391,7 +400,7 @@ func sortFoldersOrFiles(m interface{}) []string {
_, isFile := m.(File)

if !isFolder && !isFile {
panic("the function accepts only files and folders")
panic(ErrOnlyFoldersOrFiles)
}

res := make([]string, 0, reflect.ValueOf(m).Len())
Expand All @@ -418,7 +427,7 @@ func keepFoldersWithLongestPrefix(folders Folder) (res []string) {
sorted := sortFoldersOrFiles(folders)

for i := 0; i < len(folders)-1; i++ {
if !strings.HasPrefix(sorted[i+1], sorted[i]) {
if filepath.Dir(sorted[i+1]) == filepath.Dir(sorted[i]) || !strings.HasPrefix(sorted[i+1], sorted[i]) {
res = append(res, sorted[i])
}
}
Expand All @@ -431,7 +440,7 @@ func keepFoldersWithShortestPrefix(folders Folder) (res []string) {
sorted := sortFoldersOrFiles(folders)

for i := len(folders) - 1; i > 0; i-- {
if !strings.HasPrefix(sorted[i], sorted[i-1]) {
if filepath.Dir(sorted[i]) == filepath.Dir(sorted[i-1]) || !strings.HasPrefix(sorted[i], sorted[i-1]) {
res = append(res, sorted[i])
}
}
Expand Down
47 changes: 20 additions & 27 deletions mirror/mirror_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import (
"path/filepath"
"reflect"
"strconv"
"strings"
"testing"
)

Expand Down Expand Up @@ -263,17 +262,17 @@ func TestSortFoldersOrFiles2(t *testing.T) {
}

func TestKeepFoldersWithLongestPrefix(t *testing.T) {
input := Folder{"a/b/c": {}, "a": {}, "a/b": {}, "q": {}, "g": {}}
expected := []string{"a/b/c", "g", "q"}
input := Folder{"a/b/c": {}, "a": {}, "a/b": {}, "q": {}, "g": {}, "a/b/cc": {}, "aa": {}}
expected := []string{"a/b/c", "a/b/cc", "aa", "g", "q"}
got := keepFoldersWithLongestPrefix(input)
if !reflect.DeepEqual(got, expected) {
t.Errorf("input %v, got %v, expected %v", input, got, expected)
}
}

func TestKeepFoldersWithShortestPrefix(t *testing.T) {
input := Folder{"a/b/c": {}, "a": {}, "a/b": {}, "q": {}, "g": {}}
expected := []string{"q", "g", "a"}
input := Folder{"a/b/c": {}, "a": {}, "a/b": {}, "q": {}, "g": {}, "a/b/cc": {}, "aa": {}}
expected := []string{"q", "g", "aa", "a/b/cc", "a"}
got := keepFoldersWithShortestPrefix(input)
if !reflect.DeepEqual(got, expected) {
t.Errorf("input %v, got %v, expected %v", input, got, expected)
Expand All @@ -300,24 +299,24 @@ func makeTestSrcFolder(t testing.TB) {
t.Helper()

// make folders
err := os.MkdirAll(mcpp(srcPathTest+"/same_1/same_2/not_in_dst"), FolderPerm)
err := os.MkdirAll(filepath.Join(srcPathTest+"/same_1/same_2/not_in_dst"), FolderPerm)
assertError(t, nil, err)

srcFolders = Folder{"same_1": {}, mcpp("same_1/same_2"): {}, mcpp("same_1/same_2/not_in_dst"): {}}
missingFolders = Folder{mcpp("same_1/same_2/not_in_dst"): {}}
srcFolders = Folder{"same_1": {}, filepath.Join("same_1/same_2"): {}, filepath.Join("same_1/same_2/not_in_dst"): {}}
missingFolders = Folder{filepath.Join("same_1/same_2/not_in_dst"): {}}

// make files
err = ioutil.WriteFile(mcpp(srcPathTest+"/_same_1"), []byte("s"), FilePerm)
err = ioutil.WriteFile(filepath.Join(srcPathTest+"/_same_1"), []byte("s"), FilePerm)
assertError(t, nil, err)

err = ioutil.WriteFile(mcpp(srcPathTest+"/same_1/same_2/_not_in_dst"), []byte("n"), FilePerm)
err = ioutil.WriteFile(filepath.Join(srcPathTest+"/same_1/same_2/_not_in_dst"), []byte("n"), FilePerm)
assertError(t, nil, err)

err = ioutil.WriteFile(mcpp(srcPathTest+"/same_1/_different"), []byte("dd"), FilePerm)
err = ioutil.WriteFile(filepath.Join(srcPathTest+"/same_1/_different"), []byte("dd"), FilePerm)
assertError(t, nil, err)

srcFiles = File{"_same_1": 1, mcpp("same_1/same_2/_not_in_dst"): 1, mcpp("same_1/_different"): 2}
missingFiles = File{mcpp("same_1/same_2/_not_in_dst"): 1, mcpp("same_1/_different"): 2}
srcFiles = File{"_same_1": 1, filepath.Join("same_1/same_2/_not_in_dst"): 1, filepath.Join("same_1/_different"): 2}
missingFiles = File{filepath.Join("same_1/same_2/_not_in_dst"): 1, filepath.Join("same_1/_different"): 2}

sizeOfMissingFiles = 3

Expand All @@ -328,24 +327,24 @@ func makeTestDstFolder(t testing.TB) {
t.Helper()

// make folders
err := os.MkdirAll(mcpp(dstPathTest+"/same_1/same_2/not_in_src"), FolderPerm)
err := os.MkdirAll(filepath.Join(dstPathTest+"/same_1/same_2/not_in_src"), FolderPerm)
assertError(t, nil, err)

dstFolders = Folder{"same_1": {}, mcpp("same_1/same_2"): {}, mcpp("same_1/same_2/not_in_src"): {}}
foldersToClean = Folder{mcpp("same_1/same_2/not_in_src"): {}}
dstFolders = Folder{"same_1": {}, filepath.Join("same_1/same_2"): {}, filepath.Join("same_1/same_2/not_in_src"): {}}
foldersToClean = Folder{filepath.Join("same_1/same_2/not_in_src"): {}}

// make files
err = ioutil.WriteFile(mcpp(dstPathTest+"/_same_1"), []byte("s"), FilePerm)
err = ioutil.WriteFile(filepath.Join(dstPathTest+"/_same_1"), []byte("s"), FilePerm)
assertError(t, nil, err)

err = ioutil.WriteFile(mcpp(dstPathTest+"/same_1/same_2/_not_in_src"), []byte("n"), FilePerm)
err = ioutil.WriteFile(filepath.Join(dstPathTest+"/same_1/same_2/_not_in_src"), []byte("n"), FilePerm)
assertError(t, nil, err)

err = ioutil.WriteFile(mcpp(dstPathTest+"/same_1/_different"), []byte("d"), FilePerm)
err = ioutil.WriteFile(filepath.Join(dstPathTest+"/same_1/_different"), []byte("d"), FilePerm)
assertError(t, nil, err)

dstFiles = File{"_same_1": 1, mcpp("same_1/same_2/_not_in_src"): 1, mcpp("same_1/_different"): 1}
filesToClean = File{mcpp("same_1/same_2/_not_in_src"): 1}
dstFiles = File{"_same_1": 1, filepath.Join("same_1/same_2/_not_in_src"): 1, filepath.Join("same_1/_different"): 1}
filesToClean = File{filepath.Join("same_1/same_2/_not_in_src"): 1}

sizeOfFilesToClean = 1

Expand All @@ -362,12 +361,6 @@ func setFlags(t testing.TB, dst, src string, c bool) {
os.Args = append(os.Args, "-"+FlagNameDst, dst, "-"+FlagNameSrc, src, "-"+FlagNameC, strconv.FormatBool(c))
}

// mcpp makes a cross-platform path from unix path
func mcpp(unixPath string) string {
pathSplit := strings.Split(unixPath, "/")
return filepath.Join(pathSplit...)
}

func assert(t testing.TB, want, got interface{}) {
t.Helper()

Expand Down

0 comments on commit de9416a

Please sign in to comment.