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  }