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  }