github.com/orteth01/up@v0.2.0/project.go (about)

     1  package up
     2  
     3  import (
     4  	"io"
     5  	"os"
     6  	"os/exec"
     7  	"time"
     8  
     9  	"github.com/apex/log"
    10  	"github.com/pkg/errors"
    11  
    12  	"github.com/apex/up/internal/util"
    13  	"github.com/apex/up/platform"
    14  	"github.com/apex/up/platform/event"
    15  )
    16  
    17  // Project manager.
    18  type Project struct {
    19  	config   *Config
    20  	platform platform.Interface
    21  	events   event.Events
    22  }
    23  
    24  // New project.
    25  func New(c *Config, events event.Events) *Project {
    26  	return &Project{
    27  		config: c,
    28  		events: events,
    29  	}
    30  }
    31  
    32  // WithPlatform to `platform`.
    33  func (p *Project) WithPlatform(platform platform.Interface) *Project {
    34  	p.platform = platform
    35  	return p
    36  }
    37  
    38  // HookCommand returns a hook command by name or empty string.
    39  func (p *Project) HookCommand(name string) string {
    40  	switch name {
    41  	case "build":
    42  		return p.config.Hooks.Build
    43  	case "clean":
    44  		return p.config.Hooks.Clean
    45  	default:
    46  		return ""
    47  	}
    48  }
    49  
    50  // RunHook runs a hook by name.
    51  func (p *Project) RunHook(name string) error {
    52  	command := p.HookCommand(name)
    53  
    54  	if command == "" {
    55  		log.Debugf("hook %s is not defined", name)
    56  		return nil
    57  	}
    58  
    59  	defer p.events.Time("hook", event.Fields{
    60  		"name": name,
    61  	})()
    62  
    63  	cmd := exec.Command("sh", "-c", command)
    64  	cmd.Env = os.Environ()
    65  	cmd.Env = append(cmd.Env, util.Env(p.config.Environment)...)
    66  	cmd.Env = append(cmd.Env, "PATH=node_modules/.bin:"+os.Getenv("PATH"))
    67  
    68  	b, err := cmd.CombinedOutput()
    69  	if err != nil {
    70  		return errors.New(string(b))
    71  	}
    72  
    73  	return nil
    74  }
    75  
    76  // Build the project.
    77  func (p *Project) Build() error {
    78  	defer p.events.Time("platform.build", nil)()
    79  
    80  	if err := p.RunHook("build"); err != nil {
    81  		return errors.Wrap(err, "build hook")
    82  	}
    83  
    84  	return p.platform.Build()
    85  }
    86  
    87  // Deploy the project.
    88  func (p *Project) Deploy(stage string) error {
    89  	defer p.events.Time("deploy", nil)()
    90  
    91  	if err := p.Build(); err != nil {
    92  		return errors.Wrap(err, "building")
    93  	}
    94  
    95  	if err := p.deploy(stage); err != nil {
    96  		return errors.Wrap(err, "deploying")
    97  	}
    98  
    99  	if err := p.RunHook("clean"); err != nil {
   100  		return errors.Wrap(err, "clean hook")
   101  	}
   102  
   103  	return nil
   104  }
   105  
   106  // deploy stage.
   107  func (p *Project) deploy(stage string) error {
   108  	return p.platform.Deploy(stage)
   109  }
   110  
   111  // Logs for the project.
   112  func (p *Project) Logs(region, query string) platform.Logs {
   113  	return p.platform.Logs(region, query)
   114  }
   115  
   116  // URL returns the endpoint.
   117  func (p *Project) URL(region, stage string) (string, error) {
   118  	return p.platform.URL(region, stage)
   119  }
   120  
   121  // Zip returns the zip if supported by the platform.
   122  func (p *Project) Zip() (io.Reader, error) {
   123  	z, ok := p.platform.(platform.Zipper)
   124  	if !ok {
   125  		return nil, errors.Errorf("platform does not support zips")
   126  	}
   127  
   128  	return z.Zip(), nil
   129  }
   130  
   131  // CreateStack implementation.
   132  func (p *Project) CreateStack(region, version string) error {
   133  	defer p.events.Time("stack.create", event.Fields{
   134  		"region":  region,
   135  		"version": version,
   136  	})()
   137  
   138  	return p.platform.CreateStack(region, version)
   139  }
   140  
   141  // DeleteStack implementation.
   142  func (p *Project) DeleteStack(region string, wait bool) error {
   143  	defer p.events.Time("stack.delete", event.Fields{
   144  		"region": region,
   145  	})()
   146  
   147  	return p.platform.DeleteStack(region, wait)
   148  }
   149  
   150  // ShowStack implementation.
   151  func (p *Project) ShowStack(region string) error {
   152  	defer p.events.Time("stack.show", event.Fields{
   153  		"region": region,
   154  	})()
   155  
   156  	return p.platform.ShowStack(region)
   157  }
   158  
   159  // ShowMetrics implementation.
   160  func (p *Project) ShowMetrics(region, stage string, start time.Time) error {
   161  	defer p.events.Time("metrics", event.Fields{
   162  		"region": region,
   163  		"stage":  stage,
   164  		"start":  start,
   165  	})()
   166  
   167  	return p.platform.ShowMetrics(region, stage, start)
   168  }
   169  
   170  // PlanStack implementation.
   171  func (p *Project) PlanStack(region string) error {
   172  	defer p.events.Time("stack.plan", event.Fields{
   173  		"region": region,
   174  	})()
   175  
   176  	return p.platform.PlanStack(region)
   177  }
   178  
   179  // ApplyStack implementation.
   180  func (p *Project) ApplyStack(region string) error {
   181  	defer p.events.Time("stack.apply", event.Fields{
   182  		"region": region,
   183  	})()
   184  
   185  	return p.platform.ApplyStack(region)
   186  }