wrap.go 1.4 KB

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