-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapppacktoml.go
More file actions
127 lines (112 loc) · 3.33 KB
/
apppacktoml.go
File metadata and controls
127 lines (112 loc) · 3.33 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package build
import (
"context"
"fmt"
"os"
"strings"
"github.com/BurntSushi/toml"
"github.com/apppackio/codebuild-image/builder/filesystem"
"github.com/rs/zerolog/log"
)
const (
DockerBuildSystemKeyword = "dockerfile"
BuildpackBuildSystemKeyword = "buildpack"
)
type AppPackTomlBuild struct {
System string `toml:"system,omitempty"`
Buildpacks []string `toml:"buildpacks,omitempty"`
Builder string `toml:"builder,omitempty"`
Dockerfile string `toml:"dockerfile,omitempty"`
}
type AppPackTomlTest struct {
Command string `toml:"command,omitempty"`
Env []string `toml:"env,omitempty"`
}
type AppPackTomlDeploy struct {
ReleaseCommand string `toml:"release_command,omitempty"`
}
type AppPackTomlReviewApp struct {
InitializeCommand string `toml:"initialize_command,omitempty"`
PreDestroyCommand string `toml:"pre_destroy_command,omitempty"`
}
type AppPackTomlService struct {
Command string `toml:"command,omitempty"`
}
type AppPackToml struct {
Build AppPackTomlBuild `toml:"build,omitempty"`
Test AppPackTomlTest `toml:"test,omitempty"`
Deploy AppPackTomlDeploy `toml:"deploy,omitempty"`
ReviewApp AppPackTomlReviewApp `toml:"review_app,omitempty"`
Services map[string]AppPackTomlService `toml:"services,omitempty"`
}
func (a AppPackToml) UseBuildpacks() bool {
return a.Build.System == BuildpackBuildSystemKeyword || a.Build.System == ""
}
func (a AppPackToml) UseDockerfile() bool {
return a.Build.System == DockerBuildSystemKeyword
}
func (a AppPackToml) Validate() error {
if !a.UseBuildpacks() && !a.UseDockerfile() {
return fmt.Errorf("apppack.toml: [build] unknown value for system")
}
if a.UseBuildpacks() && len(a.Services) > 0 {
return fmt.Errorf("apppack.toml: [build] buildpacks cannot be used with services -- use Procfile instead")
}
for _, e := range a.Test.Env {
if !strings.Contains(e, "=") {
return fmt.Errorf("apppack.toml: [test] env %s is not in KEY=VALUE format", e)
}
}
// all validation below is for dockerfile builds
if !a.UseDockerfile() {
return nil
}
hasWeb := false
for s := range a.Services {
if s == "web" {
hasWeb = true
}
if a.Services[s].Command == "" {
return fmt.Errorf("apppack.toml: [services] service %s has no command", s)
}
}
if !hasWeb {
return fmt.Errorf("apppack.toml: [services] no web service defined")
}
return nil
}
func (a *AppPackToml) GetTestEnv() map[string]string {
env := map[string]string{
"CI": "true",
}
for e := range a.Test.Env {
kv := strings.SplitN(a.Test.Env[e], "=", 2)
if len(kv) == 2 {
env[kv[0]] = kv[1]
}
}
return env
}
func ParseAppPackToml(ctx context.Context) (*AppPackToml, error) {
var config AppPackToml
// if the file doesn't exist, just return an empty config
filename := filesystem.GetAppPackTomlFilename()
if _, err := os.Stat(filename); os.IsNotExist(err) {
log.Ctx(ctx).Debug().Msg(fmt.Sprintf("%s not found", filename))
return &config, nil
}
if _, err := toml.DecodeFile(filename, &config); err != nil {
return nil, err
}
return &config, nil
}
func (a AppPackToml) Write(ctx context.Context) error {
filename := filesystem.GetAppPackTomlFilename()
log.Ctx(ctx).Debug().Msg(fmt.Sprintf("writing %s", filename))
f, err := os.Create(filename)
if err != nil {
return err
}
defer f.Close()
return toml.NewEncoder(f).Encode(a)
}