@@ -153,7 +153,7 @@ func UnarchiveExecutables(src, dest string) error {
153153 logger .Debugf ("Unarchiving %s to %s" , src , dest )
154154 if strings .HasSuffix (src , ".zip" ) {
155155 return Unzip (src , dest )
156- } else if strings .HasSuffix (src , ".tar" ) || strings .HasSuffix (src , ".tgz" ) || strings .HasSuffix (src , ".tar.gz" ) || strings .HasSuffix (src , ".tar.xz" ) {
156+ } else if strings .HasSuffix (src , ".tar" ) || strings .HasSuffix (src , ".tgz" ) || strings .HasSuffix (src , ".tar.gz" ) || strings .HasSuffix (src , ".tar.xz" ) || strings . HasSuffix ( src , ".txz" ) {
157157 return UntarWithFilter (src , dest , func (header os.FileInfo ) string {
158158 if fmt .Sprintf ("%v" , header .Mode ()& 0100 ) != "---x------" {
159159 return ""
@@ -290,7 +290,7 @@ func UntarWithFilter(tarball, target string, filter FileFilter) error {
290290 if err != nil {
291291 return err
292292 }
293- } else if strings .HasSuffix (tarball , ".tar.xz" ) {
293+ } else if strings .HasSuffix (tarball , ".tar.xz" ) || strings . HasSuffix ( tarball , ".txz" ) {
294294 reader , err = xz .NewReader (reader )
295295 if err != nil {
296296 return err
@@ -326,15 +326,42 @@ func UntarWithFilter(tarball, target string, filter FileFilter) error {
326326 continue
327327 }
328328
329- file , err := os .OpenFile (path , os .O_CREATE | os .O_TRUNC | os .O_WRONLY , info .Mode ())
330- if err != nil {
331- return err
329+ parent := filepath .Dir (path )
330+
331+ if _ , err := os .Stat (parent ); os .IsNotExist (err ) {
332+ if err := os .MkdirAll (parent , 0755 ); err != nil {
333+ return fmt .Errorf ("failed to create directory %s: %w" , parent , err )
334+ }
332335 }
333- defer file .Close ()
334- _ , err = io .Copy (file , tarReader )
335- if err != nil {
336- return err
336+
337+ switch header .Typeflag {
338+ case tar .TypeReg :
339+ file , err := os .OpenFile (path , os .O_CREATE | os .O_RDWR , os .FileMode (header .Mode ))
340+ if err != nil {
341+ return fmt .Errorf ("failed to create file %s (mode=%v) %s" , path , info .Mode (), err )
342+ }
343+ defer file .Close ()
344+ _ , err = io .Copy (file , tarReader )
345+ if err != nil {
346+ return err
347+ }
348+
349+ case tar .TypeSymlink :
350+ if err := os .RemoveAll (path ); err != nil {
351+ return fmt .Errorf ("failed to remove symlink %s: %w" , path , err )
352+ }
353+
354+ if err := os .Symlink (header .Linkname , path ); err != nil {
355+ return fmt .Errorf ("failed to create symlink %s -> %s: %w" , path , header .Linkname , err )
356+ }
357+
358+ case tar .TypeDir :
359+ if err := os .MkdirAll (path , os .FileMode (header .Mode )); err != nil {
360+ return fmt .Errorf ("failed to create directory %s: %w" , path , err )
361+ }
362+ continue
337363 }
364+
338365 }
339366 return nil
340367}
0 commit comments