github.com/juju/charmrepo/v7@v7.0.1/testing/charm.go (about) 1 // Copyright 2012, 2013 Canonical Ltd. 2 // Licensed under the LGPLv3, see LICENCE file for details. 3 4 package testing // import "github.com/juju/charmrepo/v7/testing" 5 6 import ( 7 "fmt" 8 "os" 9 "path/filepath" 10 "runtime" 11 12 "github.com/juju/charm/v9" 13 "github.com/juju/utils/v3/fs" 14 ) 15 16 func check(err error) { 17 if err != nil { 18 panic(err) 19 } 20 } 21 22 // NewRepo returns a new testing charm repository rooted at the given 23 // path, relative to the package directory of the calling package, using 24 // defaultSeries as the default series. 25 func NewRepo(path, defaultSeries string) *Repo { 26 // Find the repo directory. This is only OK to do 27 // because this is running in a test context 28 // so we know the source is available. 29 _, file, _, ok := runtime.Caller(1) 30 if !ok { 31 panic("cannot get caller") 32 } 33 r := &Repo{ 34 path: filepath.Join(filepath.Dir(file), path), 35 defaultSeries: defaultSeries, 36 } 37 _, err := os.Stat(r.path) 38 if err != nil { 39 panic(fmt.Errorf("cannot read repository found at %q: %v", r.path, err)) 40 } 41 return r 42 } 43 44 // Repo represents a charm repository used for testing. 45 type Repo struct { 46 path string 47 defaultSeries string 48 } 49 50 func (r *Repo) Path() string { 51 return r.path 52 } 53 54 func clone(dst, src string) string { 55 dst = filepath.Join(dst, filepath.Base(src)) 56 check(fs.Copy(src, dst)) 57 return dst 58 } 59 60 // BundleDirPath returns the path to a bundle directory with the given name in the 61 // default series 62 func (r *Repo) BundleDirPath(name string) string { 63 return filepath.Join(r.Path(), "bundle", name) 64 } 65 66 // BundleDir returns the actual charm.BundleDir named name. 67 func (r *Repo) BundleDir(name string) *charm.BundleDir { 68 b, err := charm.ReadBundleDir(r.BundleDirPath(name)) 69 check(err) 70 return b 71 } 72 73 // CharmDirPath returns the path to a charm directory with the given name in the 74 // default series 75 func (r *Repo) CharmDirPath(name string) string { 76 return filepath.Join(r.Path(), r.defaultSeries, name) 77 } 78 79 // CharmDir returns the actual charm.CharmDir named name. 80 func (r *Repo) CharmDir(name string) *charm.CharmDir { 81 ch, err := charm.ReadCharmDir(r.CharmDirPath(name)) 82 check(err) 83 return ch 84 } 85 86 // ClonedDirPath returns the path to a new copy of the default charm directory 87 // named name. 88 func (r *Repo) ClonedDirPath(dst, name string) string { 89 return clone(dst, r.CharmDirPath(name)) 90 } 91 92 // ClonedDirPath returns the path to a new copy of the default bundle directory 93 // named name. 94 func (r *Repo) ClonedBundleDirPath(dst, name string) string { 95 return clone(dst, r.BundleDirPath(name)) 96 } 97 98 // RenamedClonedDirPath returns the path to a new copy of the default 99 // charm directory named name, renamed to newName. 100 func (r *Repo) RenamedClonedDirPath(dst, name, newName string) string { 101 dstPath := filepath.Join(dst, newName) 102 err := fs.Copy(r.CharmDirPath(name), dstPath) 103 check(err) 104 return dstPath 105 } 106 107 // ClonedDir returns an actual charm.CharmDir based on a new copy of the charm directory 108 // named name, in the directory dst. 109 func (r *Repo) ClonedDir(dst, name string) *charm.CharmDir { 110 ch, err := charm.ReadCharmDir(r.ClonedDirPath(dst, name)) 111 check(err) 112 return ch 113 } 114 115 // ClonedURL makes a copy of the charm directory. It will create a directory 116 // with the series name if it does not exist, and then clone the charm named 117 // name into that directory. The return value is a URL pointing at the local 118 // charm. 119 func (r *Repo) ClonedURL(dst, series, name string) *charm.URL { 120 dst = filepath.Join(dst, series) 121 if err := os.MkdirAll(dst, os.FileMode(0777)); err != nil { 122 panic(fmt.Errorf("cannot make destination directory: %v", err)) 123 } 124 clone(dst, r.CharmDirPath(name)) 125 return &charm.URL{ 126 Schema: "local", 127 Name: name, 128 Revision: -1, 129 Series: series, 130 } 131 } 132 133 // CharmArchivePath returns the path to a new charm archive file 134 // in the directory dst, created from the charm directory named name. 135 func (r *Repo) CharmArchivePath(dst, name string) string { 136 dir := r.CharmDir(name) 137 path := filepath.Join(dst, "archive.charm") 138 file, err := os.Create(path) 139 check(err) 140 defer file.Close() 141 check(dir.ArchiveTo(file)) 142 return path 143 } 144 145 // BundleArchivePath returns the path to a new bundle archive file 146 // in the directory dst, created from the bundle directory named name. 147 func (r *Repo) BundleArchivePath(dst, name string) string { 148 dir := r.BundleDir(name) 149 path := filepath.Join(dst, "archive.bundle") 150 file, err := os.Create(path) 151 check(err) 152 defer file.Close() 153 check(dir.ArchiveTo(file)) 154 return path 155 } 156 157 // CharmArchive returns an actual charm.CharmArchive created from a new 158 // charm archive file created from the charm directory named name, in 159 // the directory dst. 160 func (r *Repo) CharmArchive(dst, name string) *charm.CharmArchive { 161 ch, err := charm.ReadCharmArchive(r.CharmArchivePath(dst, name)) 162 check(err) 163 return ch 164 } 165 166 // BundleArchive returns an actual charm.BundleArchive created from a new 167 // bundle archive file created from the bundle directory named name, in 168 // the directory dst. 169 func (r *Repo) BundleArchive(dst, name string) *charm.BundleArchive { 170 b, err := charm.ReadBundleArchive(r.BundleArchivePath(dst, name)) 171 check(err) 172 return b 173 }