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  }