github.com/demonoid81/moby@v0.0.0-20200517203328-62dd8e17c460/pkg/archive/wrap.go (about)

     1  package archive // import "github.com/demonoid81/moby/pkg/archive"
     2  
     3  import (
     4  	"archive/tar"
     5  	"bytes"
     6  	"io"
     7  )
     8  
     9  // Generate generates a new archive from the content provided
    10  // as input.
    11  //
    12  // `files` is a sequence of path/content pairs. A new file is
    13  // added to the archive for each pair.
    14  // If the last pair is incomplete, the file is created with an
    15  // empty content. For example:
    16  //
    17  // Generate("foo.txt", "hello world", "emptyfile")
    18  //
    19  // The above call will return an archive with 2 files:
    20  //  * ./foo.txt with content "hello world"
    21  //  * ./empty with empty content
    22  //
    23  // FIXME: stream content instead of buffering
    24  // FIXME: specify permissions and other archive metadata
    25  func Generate(input ...string) (io.Reader, error) {
    26  	files := parseStringPairs(input...)
    27  	buf := new(bytes.Buffer)
    28  	tw := tar.NewWriter(buf)
    29  	for _, file := range files {
    30  		name, content := file[0], file[1]
    31  		hdr := &tar.Header{
    32  			Name: name,
    33  			Size: int64(len(content)),
    34  		}
    35  		if err := tw.WriteHeader(hdr); err != nil {
    36  			return nil, err
    37  		}
    38  		if _, err := tw.Write([]byte(content)); err != nil {
    39  			return nil, err
    40  		}
    41  	}
    42  	if err := tw.Close(); err != nil {
    43  		return nil, err
    44  	}
    45  	return buf, nil
    46  }
    47  
    48  func parseStringPairs(input ...string) (output [][2]string) {
    49  	output = make([][2]string, 0, len(input)/2+1)
    50  	for i := 0; i < len(input); i += 2 {
    51  		var pair [2]string
    52  		pair[0] = input[i]
    53  		if i+1 < len(input) {
    54  			pair[1] = input[i+1]
    55  		}
    56  		output = append(output, pair)
    57  	}
    58  	return
    59  }