gopkg.in/juju/charm.v6-unstable@v6.0.0-20171026192109-50d0c219b496/charm.go (about) 1 // Copyright 2011, 2012, 2013 Canonical Ltd. 2 // Licensed under the LGPLv3, see LICENCE file for details. 3 4 package charm 5 6 import ( 7 "fmt" 8 "os" 9 "strings" 10 11 "github.com/juju/loggo" 12 ) 13 14 var logger = loggo.GetLogger("juju.charm") 15 16 // The Charm interface is implemented by any type that 17 // may be handled as a charm. 18 type Charm interface { 19 Meta() *Meta 20 Config() *Config 21 Metrics() *Metrics 22 Actions() *Actions 23 Revision() int 24 } 25 26 // ReadCharm reads a Charm from path, which can point to either a charm archive or a 27 // charm directory. 28 func ReadCharm(path string) (charm Charm, err error) { 29 info, err := os.Stat(path) 30 if err != nil { 31 return nil, err 32 } 33 if info.IsDir() { 34 charm, err = ReadCharmDir(path) 35 } else { 36 charm, err = ReadCharmArchive(path) 37 } 38 if err != nil { 39 return nil, err 40 } 41 return charm, nil 42 } 43 44 // SeriesForCharm takes a requested series and a list of series supported by a 45 // charm and returns the series which is relevant. 46 // If the requested series is empty, then the first supported series is used, 47 // otherwise the requested series is validated against the supported series. 48 func SeriesForCharm(requestedSeries string, supportedSeries []string) (string, error) { 49 // Old charm with no supported series. 50 if len(supportedSeries) == 0 { 51 if requestedSeries == "" { 52 return "", missingSeriesError 53 } 54 return requestedSeries, nil 55 } 56 // Use the charm default. 57 if requestedSeries == "" { 58 return supportedSeries[0], nil 59 } 60 for _, s := range supportedSeries { 61 if s == requestedSeries { 62 return requestedSeries, nil 63 } 64 } 65 return "", &unsupportedSeriesError{requestedSeries, supportedSeries} 66 } 67 68 // missingSeriesError is used to denote that SeriesForCharm could not determine 69 // a series because a legacy charm did not declare any. 70 var missingSeriesError = fmt.Errorf("series not specified and charm does not define any") 71 72 // IsMissingSeriesError returns true if err is an missingSeriesError. 73 func IsMissingSeriesError(err error) bool { 74 return err == missingSeriesError 75 } 76 77 // UnsupportedSeriesError represents an error indicating that the requested series 78 // is not supported by the charm. 79 type unsupportedSeriesError struct { 80 requestedSeries string 81 supportedSeries []string 82 } 83 84 func (e *unsupportedSeriesError) Error() string { 85 return fmt.Sprintf( 86 "series %q not supported by charm, supported series are: %s", 87 e.requestedSeries, strings.Join(e.supportedSeries, ","), 88 ) 89 } 90 91 // NewUnsupportedSeriesError returns an error indicating that the requested series 92 // is not supported by a charm. 93 func NewUnsupportedSeriesError(requestedSeries string, supportedSeries []string) error { 94 return &unsupportedSeriesError{requestedSeries, supportedSeries} 95 } 96 97 // IsUnsupportedSeriesError returns true if err is an UnsupportedSeriesError. 98 func IsUnsupportedSeriesError(err error) bool { 99 _, ok := err.(*unsupportedSeriesError) 100 return ok 101 }