-
Notifications
You must be signed in to change notification settings - Fork 59
/
bundlearchive.go
106 lines (92 loc) · 2.48 KB
/
bundlearchive.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
// Copyright 2014 Canonical Ltd.
// Licensed under the LGPLv3, see LICENCE file for details.
package charm
import (
"bytes"
"io"
"io/ioutil"
ziputil "github.com/juju/utils/v3/zip"
)
type BundleArchive struct {
zopen zipOpener
Path string
data *BundleData
readMe string
containsOverlays bool
}
// ReadBundleArchive reads a bundle archive from the given file path.
func ReadBundleArchive(path string) (*BundleArchive, error) {
a, err := readBundleArchive(newZipOpenerFromPath(path))
if err != nil {
return nil, err
}
a.Path = path
return a, nil
}
// ReadBundleArchiveBytes reads a bundle archive from the given byte
// slice.
func ReadBundleArchiveBytes(data []byte) (*BundleArchive, error) {
zopener := newZipOpenerFromReader(bytes.NewReader(data), int64(len(data)))
return readBundleArchive(zopener)
}
// ReadBundleArchiveFromReader returns a BundleArchive that uses
// r to read the bundle. The given size must hold the number
// of available bytes in the file.
//
// Note that the caller is responsible for closing r - methods on
// the returned BundleArchive may fail after that.
func ReadBundleArchiveFromReader(r io.ReaderAt, size int64) (*BundleArchive, error) {
return readBundleArchive(newZipOpenerFromReader(r, size))
}
func readBundleArchive(zopen zipOpener) (*BundleArchive, error) {
a := &BundleArchive{
zopen: zopen,
}
zipr, err := zopen.openZip()
if err != nil {
return nil, err
}
defer zipr.Close()
reader, err := zipOpenFile(zipr, "bundle.yaml")
if err != nil {
return nil, err
}
a.data, a.containsOverlays, err = readBaseFromMultidocBundle(reader)
reader.Close()
if err != nil {
return nil, err
}
reader, err = zipOpenFile(zipr, "README.md")
if err != nil {
return nil, err
}
readMe, err := ioutil.ReadAll(reader)
if err != nil {
return nil, err
}
a.readMe = string(readMe)
return a, nil
}
// Data implements Bundle.Data.
func (a *BundleArchive) Data() *BundleData {
return a.data
}
// ReadMe implements Bundle.ReadMe.
func (a *BundleArchive) ReadMe() string {
return a.readMe
}
// ContainsOverlays implements Bundle.ReadMe.
func (a *BundleArchive) ContainsOverlays() bool {
return a.containsOverlays
}
// ExpandTo expands the bundle archive into dir, creating it if necessary.
// If any errors occur during the expansion procedure, the process will
// abort.
func (a *BundleArchive) ExpandTo(dir string) error {
zipr, err := a.zopen.openZip()
if err != nil {
return err
}
defer zipr.Close()
return ziputil.ExtractAll(zipr.Reader, dir)
}