@@ -21,6 +21,7 @@ import (
2121 "flag"
2222 "fmt"
2323 "io"
24+ "io/fs"
2425 "io/ioutil"
2526 "log"
2627 "os"
@@ -112,6 +113,53 @@ func readManifest(path string) ([]manifestEntry, error) {
112113 return entries , nil
113114}
114115
116+ func copySymlinkRecursively (src , dst string , writeFile func (src , dst string ) error , createDir func (dst string ) error ) error {
117+ target , err := os .Readlink (src )
118+ if err != nil {
119+ return err
120+ }
121+ if ! filepath .IsAbs (target ) {
122+ target = filepath .Join (src , target )
123+ }
124+
125+ return copyRecursively (target , dst , writeFile , createDir )
126+ }
127+
128+ func copyRecursively (src , dst string , writeFile func (src , dst string ) error , createDir func (dst string ) error ) error {
129+ srcInfo , err := os .Stat (src )
130+ if err != nil {
131+ return err
132+ }
133+
134+ if srcInfo .Mode ().Type ()& fs .ModeDir != 0 {
135+ return filepath .WalkDir (src , func (path string , d os.DirEntry , err error ) error {
136+ if err != nil {
137+ return err
138+ }
139+ relDst , err := filepath .Rel (src , path )
140+ if err != nil {
141+ return err
142+ }
143+
144+ if d .Type ()& fs .ModeDir != 0 {
145+ return createDir (filepath .Join (dst , relDst ))
146+ }
147+
148+ if d .Type ()& fs .ModeSymlink != 0 {
149+ return copySymlinkRecursively (path , filepath .Join (dst , relDst ), writeFile , createDir )
150+ }
151+
152+ return writeFile (path , filepath .Join (dst , relDst ))
153+ })
154+ }
155+
156+ if srcInfo .Mode ().Type ()& fs .ModeSymlink != 0 {
157+ return copySymlinkRecursively (src , dst , writeFile , createDir )
158+ }
159+
160+ return writeFile (src , dst )
161+ }
162+
115163func archivePath (out string , manifest []manifestEntry ) (err error ) {
116164 outFile , err := os .Create (out )
117165 if err != nil {
@@ -124,12 +172,12 @@ func archivePath(out string, manifest []manifestEntry) (err error) {
124172 }()
125173 outZip := zip .NewWriter (outFile )
126174
127- for _ , entry := range manifest {
128- srcFile , err := os .Open (abs ( filepath . FromSlash ( entry . Src )) )
175+ writeFile := func ( src , dst string ) error {
176+ srcFile , err := os .Open (src )
129177 if err != nil {
130178 return err
131179 }
132- w , err := outZip .Create (entry . Dst )
180+ w , err := outZip .Create (dst )
133181 if err != nil {
134182 srcFile .Close ()
135183 return err
@@ -141,6 +189,15 @@ func archivePath(out string, manifest []manifestEntry) (err error) {
141189 if err := srcFile .Close (); err != nil {
142190 return err
143191 }
192+
193+ return nil
194+ }
195+
196+ for _ , entry := range manifest {
197+ src := abs (filepath .FromSlash (entry .Src ))
198+ if err := copyRecursively (src , entry .Dst , writeFile , func (_ string ) error { return nil }); err != nil {
199+ return err
200+ }
144201 }
145202
146203 if err := outZip .Close (); err != nil {
@@ -150,15 +207,8 @@ func archivePath(out string, manifest []manifestEntry) (err error) {
150207}
151208
152209func copyPath (out string , manifest []manifestEntry ) error {
153- if err := os .MkdirAll (out , 0777 ); err != nil {
154- return err
155- }
156- for _ , entry := range manifest {
157- dst := abs (filepath .Join (out , filepath .FromSlash (entry .Dst )))
158- if err := os .MkdirAll (filepath .Dir (dst ), 0777 ); err != nil {
159- return err
160- }
161- srcFile , err := os .Open (abs (filepath .FromSlash (entry .Src )))
210+ writeFile := func (src , dst string ) error {
211+ srcFile , err := os .Open (src )
162212 if err != nil {
163213 return err
164214 }
@@ -176,7 +226,24 @@ func copyPath(out string, manifest []manifestEntry) error {
176226 if err := dstFile .Close (); err != nil {
177227 return err
178228 }
229+
230+ return nil
179231 }
232+
233+ for _ , entry := range manifest {
234+ dst := abs (filepath .Join (out , filepath .FromSlash (entry .Dst )))
235+ if err := os .MkdirAll (filepath .Dir (dst ), 0777 ); err != nil {
236+ return err
237+ }
238+
239+ src := abs (filepath .FromSlash (entry .Src ))
240+ if err := copyRecursively (src , dst , writeFile , func (dst string ) error {
241+ return os .Mkdir (dst , 0777 )
242+ }); err != nil {
243+ return err
244+ }
245+ }
246+
180247 return nil
181248}
182249
0 commit comments