ソースを参照

Merge pull request #9090 from unclejack/archive_interface

pkg/archive: add interface for Untar
unclejack 10 年 前
コミット
c0499494df
1 ファイル変更46 行追加25 行削除
  1. 46 25
      pkg/archive/archive.go

+ 46 - 25
pkg/archive/archive.go

@@ -36,10 +36,17 @@ type (
 		NoLchown    bool
 		NoLchown    bool
 		Name        string
 		Name        string
 	}
 	}
+
+	// Archiver allows the reuse of most utility functions of this package
+	// with a pluggable Untar function.
+	Archiver struct {
+		Untar func(io.Reader, string, *TarOptions) error
+	}
 )
 )
 
 
 var (
 var (
 	ErrNotImplemented = errors.New("Function not implemented")
 	ErrNotImplemented = errors.New("Function not implemented")
+	defaultArchiver   = &Archiver{Untar}
 )
 )
 
 
 const (
 const (
@@ -549,45 +556,47 @@ loop:
 	return nil
 	return nil
 }
 }
 
 
-// TarUntar is a convenience function which calls Tar and Untar, with
-// the output of one piped into the other. If either Tar or Untar fails,
-// TarUntar aborts and returns the error.
-func TarUntar(src string, dst string) error {
+func (archiver *Archiver) TarUntar(src, dst string) error {
 	log.Debugf("TarUntar(%s %s)", src, dst)
 	log.Debugf("TarUntar(%s %s)", src, dst)
 	archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed})
 	archive, err := TarWithOptions(src, &TarOptions{Compression: Uncompressed})
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	defer archive.Close()
 	defer archive.Close()
-	return Untar(archive, dst, nil)
+	return archiver.Untar(archive, dst, nil)
 }
 }
 
 
-// UntarPath is a convenience function which looks for an archive
-// at filesystem path `src`, and unpacks it at `dst`.
-func UntarPath(src, dst string) error {
+// TarUntar is a convenience function which calls Tar and Untar, with the output of one piped into the other.
+// If either Tar or Untar fails, TarUntar aborts and returns the error.
+func TarUntar(src, dst string) error {
+	return defaultArchiver.TarUntar(src, dst)
+}
+
+func (archiver *Archiver) UntarPath(src, dst string) error {
 	archive, err := os.Open(src)
 	archive, err := os.Open(src)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	defer archive.Close()
 	defer archive.Close()
-	if err := Untar(archive, dst, nil); err != nil {
+	if err := archiver.Untar(archive, dst, nil); err != nil {
 		return err
 		return err
 	}
 	}
 	return nil
 	return nil
 }
 }
 
 
-// CopyWithTar creates a tar archive of filesystem path `src`, and
-// unpacks it at filesystem path `dst`.
-// The archive is streamed directly with fixed buffering and no
-// intermediary disk IO.
-//
-func CopyWithTar(src, dst string) error {
+// UntarPath is a convenience function which looks for an archive
+// at filesystem path `src`, and unpacks it at `dst`.
+func UntarPath(src, dst string) error {
+	return defaultArchiver.UntarPath(src, dst)
+}
+
+func (archiver *Archiver) CopyWithTar(src, dst string) error {
 	srcSt, err := os.Stat(src)
 	srcSt, err := os.Stat(src)
 	if err != nil {
 	if err != nil {
 		return err
 		return err
 	}
 	}
 	if !srcSt.IsDir() {
 	if !srcSt.IsDir() {
-		return CopyFileWithTar(src, dst)
+		return archiver.CopyFileWithTar(src, dst)
 	}
 	}
 	// Create dst, copy src's content into it
 	// Create dst, copy src's content into it
 	log.Debugf("Creating dest directory: %s", dst)
 	log.Debugf("Creating dest directory: %s", dst)
@@ -595,16 +604,18 @@ func CopyWithTar(src, dst string) error {
 		return err
 		return err
 	}
 	}
 	log.Debugf("Calling TarUntar(%s, %s)", src, dst)
 	log.Debugf("Calling TarUntar(%s, %s)", src, dst)
-	return TarUntar(src, dst)
+	return archiver.TarUntar(src, dst)
 }
 }
 
 
-// CopyFileWithTar emulates the behavior of the 'cp' command-line
-// for a single file. It copies a regular file from path `src` to
-// path `dst`, and preserves all its metadata.
-//
-// If `dst` ends with a trailing slash '/', the final destination path
-// will be `dst/base(src)`.
-func CopyFileWithTar(src, dst string) (err error) {
+// CopyWithTar creates a tar archive of filesystem path `src`, and
+// unpacks it at filesystem path `dst`.
+// The archive is streamed directly with fixed buffering and no
+// intermediary disk IO.
+func CopyWithTar(src, dst string) error {
+	return defaultArchiver.CopyWithTar(src, dst)
+}
+
+func (archiver *Archiver) CopyFileWithTar(src, dst string) (err error) {
 	log.Debugf("CopyFileWithTar(%s, %s)", src, dst)
 	log.Debugf("CopyFileWithTar(%s, %s)", src, dst)
 	srcSt, err := os.Stat(src)
 	srcSt, err := os.Stat(src)
 	if err != nil {
 	if err != nil {
@@ -652,7 +663,17 @@ func CopyFileWithTar(src, dst string) (err error) {
 			err = er
 			err = er
 		}
 		}
 	}()
 	}()
-	return Untar(r, filepath.Dir(dst), nil)
+	return archiver.Untar(r, filepath.Dir(dst), nil)
+}
+
+// CopyFileWithTar emulates the behavior of the 'cp' command-line
+// for a single file. It copies a regular file from path `src` to
+// path `dst`, and preserves all its metadata.
+//
+// If `dst` ends with a trailing slash '/', the final destination path
+// will be `dst/base(src)`.
+func CopyFileWithTar(src, dst string) (err error) {
+	return defaultArchiver.CopyFileWithTar(src, dst)
 }
 }
 
 
 // CmdStream executes a command, and returns its stdout as a stream.
 // CmdStream executes a command, and returns its stdout as a stream.