github.com/profzone/eden-framework@v1.0.10/internal/generator/files/dockerfile.go (about) 1 package files 2 3 import ( 4 "encoding/json" 5 "github.com/profzone/eden-framework/pkg/executil" 6 str "github.com/profzone/eden-framework/pkg/strings" 7 "reflect" 8 "strconv" 9 "strings" 10 ) 11 12 type Dockerfile struct { 13 From string `docker:"FROM" yaml:"from,omitempty"` 14 Image string `yaml:"image"` 15 Label map[string]string `docker:"LABEL,multi" yaml:"label,omitempty"` 16 Run string `docker:"RUN,inline" yaml:"run,omitempty"` 17 WorkDir string `docker:"WORKDIR" yaml:"workdir,omitempty"` 18 Env map[string]string `docker:"ENV,multi" yaml:"env,omitempty"` 19 Add map[string]string `docker:"ADD,join" yaml:"add,omitempty"` 20 Expose []string `docker:"EXPOSE" yaml:"expose,omitempty"` 21 Volume []string `docker:"VOLUME,array" yaml:"volume,omitempty"` 22 Cmd []string `docker:"CMD,array" yaml:"cmd,omitempty"` 23 EntryPoint []string `docker:"ENTRYPOINT,array" yaml:"entrypoint,omitempty"` 24 } 25 26 func (d *Dockerfile) String() string { 27 envVars := executil.EnvVars{} 28 envVars.LoadFromEnviron() 29 return envVars.Parse(GetDockerfileTemplate(*d)) 30 } 31 32 func (d Dockerfile) AddContent(from string, to string) *Dockerfile { 33 if d.Add == nil { 34 d.Add = map[string]string{} 35 } 36 d.Add[from] = to 37 return &d 38 } 39 40 func (d Dockerfile) AddLabel(label string, content string) *Dockerfile { 41 if d.Label == nil { 42 d.Label = map[string]string{} 43 } 44 d.Label[label] = content 45 return &d 46 } 47 48 func (d Dockerfile) AddEnv(key string, value string) *Dockerfile { 49 if d.Env == nil { 50 d.Env = map[string]string{} 51 } 52 d.Env[key] = value 53 return &d 54 } 55 56 func (d Dockerfile) WithExpose(exposes ...string) *Dockerfile { 57 d.Expose = exposes 58 return &d 59 } 60 61 func (d Dockerfile) WithVolume(volumes ...string) *Dockerfile { 62 d.Volume = volumes 63 return &d 64 } 65 66 func (d Dockerfile) WithWorkDir(dir string) *Dockerfile { 67 d.WorkDir = dir 68 return &d 69 } 70 71 func (d Dockerfile) WithCmd(cmd ...string) *Dockerfile { 72 d.Cmd = cmd 73 return &d 74 } 75 76 func GetDockerfileTemplate(d Dockerfile) string { 77 dockerfileConfig := make([]string, 0) 78 79 appendDockerConfig := func(dockerKey string, value string) { 80 dockerfileConfig = append( 81 dockerfileConfig, 82 strings.Join([]string{dockerKey, value}, " "), 83 ) 84 } 85 86 tpe := reflect.TypeOf(d) 87 rv := reflect.Indirect(reflect.ValueOf(d)) 88 89 for i := 0; i < tpe.NumField(); i++ { 90 field := tpe.Field(i) 91 dockerTag := field.Tag.Get("docker") 92 dockerKeys := strings.Split(dockerTag, ",") 93 dockerKey := dockerKeys[0] 94 dockerFlags := dockerKeys[1:] 95 96 if len(dockerKey) > 0 { 97 value := rv.FieldByName(field.Name) 98 99 switch field.Type.Kind() { 100 case reflect.String: 101 if len(value.String()) > 0 { 102 inline := str.StringIncludes(dockerFlags, "inline") 103 if inline { 104 appendDockerConfig(dockerKey, value.String()) 105 } else { 106 appendDockerConfig(dockerKey, mayQuote(value.String())) 107 } 108 } 109 case reflect.Slice: 110 jsonArray := str.StringIncludes(dockerFlags, "array") 111 slice := make([]string, 0) 112 for i := 0; i < value.Len(); i++ { 113 slice = append(slice, value.Index(i).String()) 114 } 115 if len(slice) > 0 { 116 if jsonArray { 117 jsonString, err := json.Marshal(slice) 118 if err != nil { 119 panic(err) 120 } 121 appendDockerConfig( 122 dockerKey, 123 string(jsonString), 124 ) 125 } else { 126 appendDockerConfig( 127 dockerKey, 128 strings.Join(slice, ""), 129 ) 130 } 131 } 132 133 case reflect.Map: 134 multi := str.StringIncludes(dockerFlags, "multi") 135 join := str.StringIncludes(dockerFlags, "join") 136 137 if join { 138 destMap := map[string][]string{} 139 for _, key := range value.MapKeys() { 140 dest := value.MapIndex(key).String() 141 if destMap[dest] == nil { 142 destMap[dest] = []string{} 143 } 144 destMap[dest] = append(destMap[dest], key.String()) 145 } 146 for dest, src := range destMap { 147 appendDockerConfig( 148 dockerKey, 149 strings.Join(append(src, dest), " "), 150 ) 151 } 152 } else if multi { 153 keyValues := []string{} 154 for _, key := range value.MapKeys() { 155 keyValues = append( 156 keyValues, 157 key.String()+"="+mayQuote(value.MapIndex(key).String()), 158 ) 159 } 160 if len(keyValues) > 0 { 161 appendDockerConfig( 162 dockerKey, 163 strings.Join(keyValues, " "), 164 ) 165 } 166 } else { 167 for _, key := range value.MapKeys() { 168 appendDockerConfig( 169 dockerKey, 170 strings.Join([]string{key.String(), mayQuote(value.MapIndex(key).String())}, " "), 171 ) 172 } 173 } 174 } 175 } 176 } 177 178 return strings.Join(dockerfileConfig, "\n") 179 } 180 181 func mayQuote(s string) string { 182 if s == "" || strings.Index(s, " ") > -1 { 183 return strconv.Quote(s) 184 } 185 return s 186 }