github.com/skabbes/up@v0.2.1/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 }