github.com/webonyx/up@v0.7.4-0.20180808230834-91b94e551323/config/runtimes.go (about) 1 package config 2 3 import ( 4 "os" 5 6 "github.com/apex/up/internal/util" 7 "github.com/pkg/errors" 8 ) 9 10 // Runtime is an app runtime. 11 type Runtime string 12 13 // Runtimes available. 14 const ( 15 RuntimeUnknown Runtime = "unknown" 16 RuntimeGo = "go" 17 RuntimeNode = "node" 18 RuntimeClojure = "clojure" 19 RuntimeCrystal = "crystal" 20 RuntimePython = "python" 21 RuntimeStatic = "static" 22 RuntimeJavaMaven = "java maven" 23 RuntimeJavaGradle = "java gradle" 24 ) 25 26 // inferRuntime returns the runtime based on files present in the CWD. 27 func inferRuntime() Runtime { 28 switch { 29 case util.Exists("main.go"): 30 return RuntimeGo 31 case util.Exists("main.cr"): 32 return RuntimeCrystal 33 case util.Exists("package.json"): 34 return RuntimeNode 35 case util.Exists("app.js"): 36 return RuntimeNode 37 case util.Exists("project.clj"): 38 return RuntimeClojure 39 case util.Exists("pom.xml"): 40 return RuntimeJavaMaven 41 case util.Exists("build.gradle"): 42 return RuntimeJavaGradle 43 case util.Exists("app.py"): 44 return RuntimePython 45 case util.Exists("index.html"): 46 return RuntimeStatic 47 default: 48 return RuntimeUnknown 49 } 50 } 51 52 // runtimeConfig performs config inferences based on what Up thinks the runtime is. 53 func runtimeConfig(runtime Runtime, c *Config) error { 54 switch runtime { 55 case RuntimeGo: 56 golang(c) 57 case RuntimeClojure: 58 clojureLein(c) 59 case RuntimeJavaMaven: 60 javaMaven(c) 61 case RuntimeJavaGradle: 62 javaGradle(c) 63 case RuntimeCrystal: 64 crystal(c) 65 case RuntimePython: 66 python(c) 67 case RuntimeStatic: 68 c.Type = "static" 69 case RuntimeNode: 70 if err := nodejs(c); err != nil { 71 return err 72 } 73 } 74 return nil 75 } 76 77 // golang config. 78 func golang(c *Config) { 79 if c.Hooks.Build.IsEmpty() { 80 c.Hooks.Build = Hook{`GOOS=linux GOARCH=amd64 go build -o server *.go`} 81 } 82 83 if c.Hooks.Clean.IsEmpty() { 84 c.Hooks.Clean = Hook{`rm server`} 85 } 86 87 if s := c.Stages.GetByName("development"); s != nil { 88 if s.Proxy.Command == "" { 89 s.Proxy.Command = "go run *.go" 90 } 91 } 92 } 93 94 // java gradle config. 95 func javaGradle(c *Config) { 96 if c.Proxy.Command == "" { 97 c.Proxy.Command = "java -jar server.jar" 98 } 99 100 if c.Hooks.Build.IsEmpty() { 101 // assumes build results in a shaded jar named server.jar 102 if util.Exists("gradlew") { 103 c.Hooks.Build = Hook{`./gradlew clean build && cp build/libs/server.jar .`} 104 } else { 105 c.Hooks.Build = Hook{`gradle clean build && cp build/libs/server.jar .`} 106 } 107 } 108 109 if c.Hooks.Clean.IsEmpty() { 110 c.Hooks.Clean = Hook{`rm server.jar && gradle clean`} 111 } 112 } 113 114 // java maven config. 115 func javaMaven(c *Config) { 116 if c.Proxy.Command == "" { 117 c.Proxy.Command = "java -jar server.jar" 118 } 119 120 if c.Hooks.Build.IsEmpty() { 121 // assumes package results in a shaded jar named server.jar 122 if util.Exists("mvnw") { 123 c.Hooks.Build = Hook{`./mvnw clean package && cp target/server.jar .`} 124 } else { 125 c.Hooks.Build = Hook{`mvn clean package && cp target/server.jar .`} 126 } 127 } 128 129 if c.Hooks.Clean.IsEmpty() { 130 c.Hooks.Clean = Hook{`rm server.jar && mvn clean`} 131 } 132 } 133 134 // clojure lein config. 135 func clojureLein(c *Config) { 136 if c.Proxy.Command == "" { 137 c.Proxy.Command = "java -jar server.jar" 138 } 139 140 if c.Hooks.Build.IsEmpty() { 141 // assumes package results in a shaded jar named server.jar 142 c.Hooks.Build = Hook{`lein uberjar && cp target/*-standalone.jar server.jar`} 143 } 144 145 if c.Hooks.Clean.IsEmpty() { 146 c.Hooks.Clean = Hook{`lein clean && rm server.jar`} 147 } 148 } 149 150 // crystal config. 151 func crystal(c *Config) { 152 if c.Hooks.Build.IsEmpty() { 153 c.Hooks.Build = Hook{`docker run --rm -v $(pwd):/src -w /src tjholowaychuk/up-crystal crystal build --link-flags -static -o server main.cr`} 154 } 155 156 if c.Hooks.Clean.IsEmpty() { 157 c.Hooks.Clean = Hook{`rm server`} 158 } 159 160 if s := c.Stages.GetByName("development"); s != nil { 161 if s.Proxy.Command == "" { 162 s.Proxy.Command = "crystal run main.cr" 163 } 164 } 165 } 166 167 // nodejs config. 168 func nodejs(c *Config) error { 169 var pkg struct { 170 Scripts struct { 171 Start string `json:"start"` 172 Build string `json:"build"` 173 } `json:"scripts"` 174 } 175 176 // read package.json 177 if err := util.ReadFileJSON("package.json", &pkg); err != nil && !os.IsNotExist(errors.Cause(err)) { 178 return err 179 } 180 181 // use "start" script unless explicitly defined in up.json 182 if c.Proxy.Command == "" { 183 if s := pkg.Scripts.Start; s == "" { 184 c.Proxy.Command = `node app.js` 185 } else { 186 c.Proxy.Command = s 187 } 188 } 189 190 // use "build" script unless explicitly defined in up.json 191 if c.Hooks.Build.IsEmpty() { 192 c.Hooks.Build = Hook{pkg.Scripts.Build} 193 } 194 195 return nil 196 } 197 198 // python config. 199 func python(c *Config) { 200 if c.Proxy.Command == "" { 201 c.Proxy.Command = "python app.py" 202 } 203 204 // Only add build & clean hooks if a requirements.txt exists 205 if !util.Exists("requirements.txt") { 206 return 207 } 208 209 // Set PYTHONPATH env 210 if c.Environment == nil { 211 c.Environment = Environment{} 212 } 213 c.Environment["PYTHONPATH"] = ".pypath/" 214 215 // Copy libraries into .pypath/ 216 if c.Hooks.Build.IsEmpty() { 217 c.Hooks.Build = Hook{`mkdir -p .pypath/ && pip install -r requirements.txt -t .pypath/`} 218 } 219 220 // Clean .pypath/ 221 if c.Hooks.Clean.IsEmpty() { 222 c.Hooks.Clean = Hook{`rm -r .pypath/`} 223 } 224 }