Skip to content

Commit 2016358

Browse files
authored
Preserve Filemode during copy according to the --technology (#59)
1 parent bbb7ded commit 2016358

File tree

2 files changed

+122
-26
lines changed

2 files changed

+122
-26
lines changed

pkg/move/technologies.go

Lines changed: 54 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package move
22

33
import (
44
"encoding/json"
5+
"os"
56
"path/filepath"
67
"strings"
78

@@ -41,33 +42,68 @@ func CopyByTechnology(log logr.Logger, fs afero.Afero, from string, to string, t
4142
return err
4243
}
4344

45+
err = copyByList(log, fs, from, to, filteredPaths)
46+
if err != nil {
47+
return err
48+
}
49+
50+
return nil
51+
}
52+
53+
func copyByList(log logr.Logger, fs afero.Afero, from string, to string, paths []string) error {
4454
oldUmask := unix.Umask(0000)
4555
defer unix.Umask(oldUmask)
4656

47-
for _, sourceFilePath := range filteredPaths {
48-
targetFilePath := filepath.Join(to, strings.Split(sourceFilePath, from)[1])
57+
fromStat, err := fs.Stat(from)
58+
if err != nil {
59+
log.Error(err, "error checking stat mode from source folder")
4960

50-
sourceStatMode, err := fs.Stat(from)
51-
if err != nil {
52-
log.Error(err, "error checking stat mode from source folder")
61+
return err
62+
}
5363

54-
return err
55-
}
64+
err = fs.MkdirAll(to, fromStat.Mode())
65+
if err != nil {
66+
log.Error(err, "error creating target folder")
67+
68+
return err
69+
}
5670

57-
err = fs.MkdirAll(filepath.Dir(targetFilePath), sourceStatMode.Mode())
58-
if err != nil {
59-
log.Error(err, "error creating target folder")
71+
for _, path := range paths {
72+
splitPath := strings.Split(path, string(filepath.Separator))
6073

61-
return err
62-
}
74+
walkedPath := ""
75+
for _, subPath := range splitPath {
76+
walkedPath = filepath.Join(walkedPath, subPath)
77+
sourcePath := filepath.Join(from, walkedPath)
78+
targetPath := filepath.Join(to, walkedPath)
6379

64-
log.V(1).Info("copying file %s to %s", "from", sourceFilePath, "to", targetFilePath)
80+
sourceStat, err := fs.Stat(sourcePath)
81+
if err != nil {
82+
log.Error(err, "failed checking stat mode from source", "path", sourcePath)
6583

66-
err = fsutils.CopyFile(fs, sourceFilePath, targetFilePath)
67-
if err != nil {
68-
log.Error(err, "error copying file")
84+
return err
85+
}
86+
87+
if sourceStat.IsDir() {
88+
err := fs.Mkdir(targetPath, sourceStat.Mode())
89+
if err != nil && !os.IsExist(err) {
90+
log.Error(err, "failed to create new dir", "path", targetPath)
91+
92+
return err
93+
} else {
94+
log.V(1).Info("created new dir", "from", sourcePath, "to", targetPath, "mode", sourceStat.Mode())
95+
}
96+
} else {
97+
log.V(1).Info("copying file", "from", sourcePath, "to", targetPath, "mode", sourceStat.Mode())
98+
99+
err = fsutils.CopyFile(fs, sourcePath, targetPath)
100+
if err != nil {
101+
log.Error(err, "error copying file")
102+
103+
return err
104+
}
105+
}
69106

70-
return err
71107
}
72108
}
73109

@@ -100,7 +136,7 @@ func filterFilesByTechnology(log logr.Logger, fs afero.Afero, source string, tec
100136
log.V(1).Info("collecting files for technology", "tech", tech, "arch", arch)
101137

102138
for _, file := range files {
103-
paths = append(paths, filepath.Join(source, file.Path))
139+
paths = append(paths, file.Path)
104140
}
105141
}
106142
}

pkg/move/technologies_test.go

Lines changed: 68 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ package move
22

33
import (
44
"fmt"
5+
"io/fs"
56
"path/filepath"
67
"testing"
78

@@ -89,6 +90,68 @@ func TestCopyFolderWithTechnologyFiltering(t *testing.T) {
8990
})
9091
}
9192

93+
func TestCopyByList(t *testing.T) {
94+
dirs := []string{
95+
"./folder",
96+
"./folder/sub",
97+
"./folder/sub/child",
98+
}
99+
dirModes := []fs.FileMode{
100+
0777,
101+
0776,
102+
0775,
103+
}
104+
105+
filesNames := []string{
106+
"f1.txt",
107+
"runtime",
108+
"log",
109+
}
110+
fileModes := []fs.FileMode{
111+
0764,
112+
0773,
113+
0772,
114+
}
115+
116+
fs := afero.Afero{Fs: afero.NewMemMapFs()}
117+
// create an FS where there are multiple sub dirs and files, each with their own file modes
118+
for i := range len(dirs) {
119+
err := fs.Mkdir(dirs[i], dirModes[i])
120+
require.NoError(t, err)
121+
err = fs.WriteFile(filepath.Join(dirs[i], filesNames[i]), []byte(fmt.Sprintf("%d", i)), fileModes[i])
122+
require.NoError(t, err)
123+
}
124+
125+
// reverse the list, so the longest path is the first
126+
fileList := []string{}
127+
for i := len(dirs) - 1; i >= 0; i-- {
128+
fileList = append(fileList, filepath.Join(dirs[i], filesNames[i]))
129+
}
130+
131+
targetDir := "./target"
132+
133+
err := copyByList(testLog, fs, "./", targetDir, fileList)
134+
require.NoError(t, err)
135+
136+
for i := range len(dirs) {
137+
targetStat, err := fs.Stat(filepath.Join(targetDir, dirs[i]))
138+
require.NoError(t, err)
139+
assert.Equal(t, dirModes[i], targetStat.Mode().Perm(), targetStat.Name())
140+
141+
sourceStat, err := fs.Stat(dirs[i])
142+
require.NoError(t, err)
143+
assert.Equal(t, sourceStat.Mode(), targetStat.Mode(), targetStat.Name())
144+
145+
targetStat, err = fs.Stat(filepath.Join(targetDir, dirs[i], filesNames[i]))
146+
require.NoError(t, err)
147+
assert.Equal(t, fileModes[i], targetStat.Mode().Perm(), targetStat.Name())
148+
149+
sourceStat, err = fs.Stat(filepath.Join(dirs[i], filesNames[i]))
150+
require.NoError(t, err)
151+
assert.Equal(t, sourceStat.Mode(), targetStat.Mode(), targetStat.Name())
152+
}
153+
}
154+
92155
func TestFilterFilesByTechnology(t *testing.T) {
93156
fs := afero.Afero{Fs: afero.NewMemMapFs()}
94157

@@ -111,25 +174,22 @@ func TestFilterFilesByTechnology(t *testing.T) {
111174
}
112175
}`
113176
_ = afero.WriteFile(fs, filepath.Join(sourceDir, "manifest.json"), []byte(manifestContent), 0644)
114-
_ = afero.WriteFile(fs, filepath.Join(sourceDir, "fileA1.txt"), []byte("a1 content"), 0644)
115-
_ = afero.WriteFile(fs, filepath.Join(sourceDir, "fileA2.txt"), []byte("a2 content"), 0644)
116-
_ = afero.WriteFile(fs, filepath.Join(sourceDir, "fileB1.txt"), []byte("b1 content"), 0644)
117177

118178
t.Run("filter single technology", func(t *testing.T) {
119179
paths, err := filterFilesByTechnology(testLog, fs, sourceDir, []string{"java"})
120180
require.NoError(t, err)
121181
assert.ElementsMatch(t, []string{
122-
filepath.Join(sourceDir, "fileA1.txt"),
123-
filepath.Join(sourceDir, "fileA2.txt"),
182+
filepath.Join("fileA1.txt"),
183+
filepath.Join("fileA2.txt"),
124184
}, paths)
125185
})
126186
t.Run("filter multiple technologies", func(t *testing.T) {
127187
paths, err := filterFilesByTechnology(testLog, fs, sourceDir, []string{"java", "python"})
128188
require.NoError(t, err)
129189
assert.ElementsMatch(t, []string{
130-
filepath.Join(sourceDir, "fileA1.txt"),
131-
filepath.Join(sourceDir, "fileA2.txt"),
132-
filepath.Join(sourceDir, "fileB1.txt"),
190+
filepath.Join("fileA1.txt"),
191+
filepath.Join("fileA2.txt"),
192+
filepath.Join("fileB1.txt"),
133193
}, paths)
134194
})
135195
t.Run("not filter non-existing technology", func(t *testing.T) {

0 commit comments

Comments
 (0)