| OLD | NEW |
| 1 package main | 1 package main |
| 2 | 2 |
| 3 import ( | 3 import ( |
| 4 "bytes" | 4 "bytes" |
| 5 "crypto/md5" | 5 "crypto/md5" |
| 6 "database/sql" | 6 "database/sql" |
| 7 "encoding/base64" | 7 "encoding/base64" |
| 8 "encoding/binary" | 8 "encoding/binary" |
| 9 "encoding/json" | 9 "encoding/json" |
| 10 "flag" | 10 "flag" |
| (...skipping 18 matching lines...) Expand all Loading... |
| 29 ) | 29 ) |
| 30 | 30 |
| 31 import ( | 31 import ( |
| 32 "github.com/fiorix/go-web/autogzip" | 32 "github.com/fiorix/go-web/autogzip" |
| 33 _ "github.com/go-sql-driver/mysql" | 33 _ "github.com/go-sql-driver/mysql" |
| 34 _ "github.com/mattn/go-sqlite3" | 34 _ "github.com/mattn/go-sqlite3" |
| 35 "github.com/rcrowley/go-metrics" | 35 "github.com/rcrowley/go-metrics" |
| 36 ) | 36 ) |
| 37 | 37 |
| 38 const ( | 38 const ( |
| 39 RUN_GYP = `../../experimental/webtry/gyp_for_webtry %s -Dskia_gpu=0` | |
| 40 RUN_NINJA = `ninja -C ../../../inout/Release %s` | |
| 41 | 39 |
| 42 DEFAULT_SAMPLE = `void draw(SkCanvas* canvas) { | 40 DEFAULT_SAMPLE = `void draw(SkCanvas* canvas) { |
| 43 SkPaint p; | 41 SkPaint p; |
| 44 p.setColor(SK_ColorRED); | 42 p.setColor(SK_ColorRED); |
| 45 p.setAntiAlias(true); | 43 p.setAntiAlias(true); |
| 46 p.setStyle(SkPaint::kStroke_Style); | 44 p.setStyle(SkPaint::kStroke_Style); |
| 47 p.setStrokeWidth(10); | 45 p.setStrokeWidth(10); |
| 48 | 46 |
| 49 canvas->drawLine(20, 20, 100, 100, p); | 47 canvas->drawLine(20, 20, 100, 100, p); |
| 50 }` | 48 }` |
| (...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 193 filepath.Join(cwd, "templates/footercommon.html"), | 191 filepath.Join(cwd, "templates/footercommon.html"), |
| 194 ) | 192 ) |
| 195 if err != nil { | 193 if err != nil { |
| 196 panic(err) | 194 panic(err) |
| 197 } | 195 } |
| 198 | 196 |
| 199 // The git command returns output of the format: | 197 // The git command returns output of the format: |
| 200 // | 198 // |
| 201 // f672cead70404080a991ebfb86c38316a4589b23 2014-04-27 19:21:51 +0000 | 199 // f672cead70404080a991ebfb86c38316a4589b23 2014-04-27 19:21:51 +0000 |
| 202 // | 200 // |
| 203 » logOutput, err := doCmd(`git log --format=%H%x20%ai HEAD^..HEAD`, true) | 201 » logOutput, err := doCmd(`git log --format=%H%x20%ai HEAD^..HEAD`) |
| 204 if err != nil { | 202 if err != nil { |
| 205 panic(err) | 203 panic(err) |
| 206 } | 204 } |
| 207 logInfo := strings.Split(logOutput, " ") | 205 logInfo := strings.Split(logOutput, " ") |
| 208 gitHash = logInfo[0] | 206 gitHash = logInfo[0] |
| 209 gitInfo = logInfo[1] + " " + logInfo[2] + " " + logInfo[0][0:6] | 207 gitInfo = logInfo[1] + " " + logInfo[2] + " " + logInfo[0][0:6] |
| 210 | 208 |
| 211 // Connect to MySQL server. First, get the password from the metadata se
rver. | 209 // Connect to MySQL server. First, get the password from the metadata se
rver. |
| 212 // See https://developers.google.com/compute/docs/metadata#custom. | 210 // See https://developers.google.com/compute/docs/metadata#custom. |
| 213 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i
nstance/attributes/password", nil) | 211 req, err := http.NewRequest("GET", "http://metadata/computeMetadata/v1/i
nstance/attributes/password", nil) |
| (...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 387 } | 385 } |
| 388 | 386 |
| 389 // response is serialized to JSON as a response to POSTs. | 387 // response is serialized to JSON as a response to POSTs. |
| 390 type response struct { | 388 type response struct { |
| 391 Message string `json:"message"` | 389 Message string `json:"message"` |
| 392 StdOut string `json:"stdout"` | 390 StdOut string `json:"stdout"` |
| 393 Img string `json:"img"` | 391 Img string `json:"img"` |
| 394 Hash string `json:"hash"` | 392 Hash string `json:"hash"` |
| 395 } | 393 } |
| 396 | 394 |
| 397 // doCmd executes the given command line string in either the out/Debug | 395 // doCmd executes the given command line string; the command being |
| 398 // directory or the inout directory. Returns the stdout and stderr. | 396 // run is expected to not care what its current working directory is. |
| 399 func doCmd(commandLine string, moveToDebug bool) (string, error) { | 397 // Returns the stdout and stderr. |
| 398 func doCmd(commandLine string) (string, error) { |
| 400 log.Printf("Command: %q\n", commandLine) | 399 log.Printf("Command: %q\n", commandLine) |
| 401 programAndArgs := strings.SplitN(commandLine, " ", 2) | 400 programAndArgs := strings.SplitN(commandLine, " ", 2) |
| 402 program := programAndArgs[0] | 401 program := programAndArgs[0] |
| 403 args := []string{} | 402 args := []string{} |
| 404 if len(programAndArgs) > 1 { | 403 if len(programAndArgs) > 1 { |
| 405 args = strings.Split(programAndArgs[1], " ") | 404 args = strings.Split(programAndArgs[1], " ") |
| 406 } | 405 } |
| 407 cmd := exec.Command(program, args...) | 406 cmd := exec.Command(program, args...) |
| 408 abs, err := filepath.Abs("../../out/Debug") | |
| 409 if err != nil { | |
| 410 return "", fmt.Errorf("Failed to find absolute path to Debug dir
ectory.") | |
| 411 } | |
| 412 if moveToDebug { | |
| 413 cmd.Dir = abs | |
| 414 } else if !*useChroot { // Don't set cmd.Dir when using chroot. | |
| 415 abs, err := filepath.Abs("../../../inout") | |
| 416 if err != nil { | |
| 417 return "", fmt.Errorf("Failed to find absolute path to i
nout directory.") | |
| 418 } | |
| 419 cmd.Dir = abs | |
| 420 } | |
| 421 log.Printf("Run in directory: %q\n", cmd.Dir) | |
| 422 message, err := cmd.CombinedOutput() | 407 message, err := cmd.CombinedOutput() |
| 423 log.Printf("StdOut + StdErr: %s\n", string(message)) | 408 log.Printf("StdOut + StdErr: %s\n", string(message)) |
| 424 if err != nil { | 409 if err != nil { |
| 425 log.Printf("Exit status: %s\n", err.Error()) | 410 log.Printf("Exit status: %s\n", err.Error()) |
| 426 return string(message), fmt.Errorf("Failed to run command.") | 411 return string(message), fmt.Errorf("Failed to run command.") |
| 427 } | 412 } |
| 428 return string(message), nil | 413 return string(message), nil |
| 429 } | 414 } |
| 430 | 415 |
| 431 // reportError formats an HTTP error response and also logs the detailed error m
essage. | 416 // reportError formats an HTTP error response and also logs the detailed error m
essage. |
| (...skipping 390 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 822 if err != nil { | 807 if err != nil { |
| 823 reportTryError(w, r, err, "Failed to write the code to c
ompile.", hash) | 808 reportTryError(w, r, err, "Failed to write the code to c
ompile.", hash) |
| 824 return | 809 return |
| 825 } | 810 } |
| 826 writeToDatabase(hash, request.Code, request.Name, request.Source
) | 811 writeToDatabase(hash, request.Code, request.Name, request.Source
) |
| 827 err = expandGyp(hash) | 812 err = expandGyp(hash) |
| 828 if err != nil { | 813 if err != nil { |
| 829 reportTryError(w, r, err, "Failed to write the gyp file.
", hash) | 814 reportTryError(w, r, err, "Failed to write the gyp file.
", hash) |
| 830 return | 815 return |
| 831 } | 816 } |
| 832 » » message, err := doCmd(fmt.Sprintf(RUN_GYP, hash), true) | 817 » » cmd := "scripts/fiddle_wrapper " + hash |
| 833 » » if err != nil { | 818 » » if *useChroot { |
| 834 » » » message = cleanCompileOutput(message, hash) | 819 » » » cmd = "schroot -c webtry --directory=/ -- /skia_build/sk
ia/experimental/webtry/" + cmd |
| 835 » » » reportTryError(w, r, err, message, hash) | 820 » » } |
| 836 » » » return | |
| 837 » » } | |
| 838 » » linkMessage, err := doCmd(fmt.Sprintf(RUN_NINJA, hash), true) | |
| 839 » » if err != nil { | |
| 840 » » » linkMessage = cleanCompileOutput(linkMessage, hash) | |
| 841 » » » reportTryError(w, r, err, linkMessage, hash) | |
| 842 » » » return | |
| 843 » » } | |
| 844 » » message += linkMessage | |
| 845 » » cmd := hash + " --out " + hash + ".png" | |
| 846 if request.Source > 0 { | 821 if request.Source > 0 { |
| 847 » » » cmd += fmt.Sprintf(" --source image-%d.png", request.So
urce) | 822 » » » cmd += fmt.Sprintf(" image-%d.png", request.Source) |
| 848 » » } | |
| 849 » » if *useChroot { | |
| 850 » » » cmd = "schroot -c webtry --directory=/inout -- /inout/Re
lease/" + cmd | |
| 851 » » } else { | |
| 852 » » » abs, err := filepath.Abs("../../../inout/Release") | |
| 853 » » » if err != nil { | |
| 854 » » » » reportTryError(w, r, err, "Failed to find execut
able directory.", hash) | |
| 855 » » » » return | |
| 856 » » » } | |
| 857 » » » cmd = abs + "/" + cmd | |
| 858 } | 823 } |
| 859 | 824 |
| 860 » » execMessage, err := doCmd(cmd, false) | 825 » » message, err := doCmd(cmd) |
| 861 if err != nil { | 826 if err != nil { |
| 862 » » » reportTryError(w, r, err, "Failed to run the code:\n"+ex
ecMessage, hash) | 827 » » » reportTryError(w, r, err, "Failed to run the code:\n"+me
ssage, hash) |
| 863 return | 828 return |
| 864 } | 829 } |
| 865 png, err := ioutil.ReadFile("../../../inout/" + hash + ".png") | 830 png, err := ioutil.ReadFile("../../../inout/" + hash + ".png") |
| 866 if err != nil { | 831 if err != nil { |
| 867 reportTryError(w, r, err, "Failed to open the generated
PNG.", hash) | 832 reportTryError(w, r, err, "Failed to open the generated
PNG.", hash) |
| 868 return | 833 return |
| 869 } | 834 } |
| 870 | 835 |
| 871 m := response{ | 836 m := response{ |
| 872 Message: message, | 837 Message: message, |
| 873 StdOut: execMessage, | |
| 874 Img: base64.StdEncoding.EncodeToString([]byte(png)), | 838 Img: base64.StdEncoding.EncodeToString([]byte(png)), |
| 875 Hash: hash, | 839 Hash: hash, |
| 876 } | 840 } |
| 877 resp, err := json.Marshal(m) | 841 resp, err := json.Marshal(m) |
| 878 if err != nil { | 842 if err != nil { |
| 879 reportTryError(w, r, err, "Failed to serialize a respons
e.", hash) | 843 reportTryError(w, r, err, "Failed to serialize a respons
e.", hash) |
| 880 return | 844 return |
| 881 } | 845 } |
| 882 w.Header().Set("Content-Type", "application/json") | 846 w.Header().Set("Content-Type", "application/json") |
| 883 w.Write(resp) | 847 w.Write(resp) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 894 http.HandleFunc("/sources/", autogzip.HandleFunc(sourcesHandler)) | 858 http.HandleFunc("/sources/", autogzip.HandleFunc(sourcesHandler)) |
| 895 | 859 |
| 896 // Resources are served directly | 860 // Resources are served directly |
| 897 // TODO add support for caching/etags/gzip | 861 // TODO add support for caching/etags/gzip |
| 898 http.Handle("/res/", autogzip.Handle(http.FileServer(http.Dir("./")))) | 862 http.Handle("/res/", autogzip.Handle(http.FileServer(http.Dir("./")))) |
| 899 | 863 |
| 900 // TODO Break out /c/ as it's own handler. | 864 // TODO Break out /c/ as it's own handler. |
| 901 http.HandleFunc("/", autogzip.HandleFunc(mainHandler)) | 865 http.HandleFunc("/", autogzip.HandleFunc(mainHandler)) |
| 902 log.Fatal(http.ListenAndServe(*port, nil)) | 866 log.Fatal(http.ListenAndServe(*port, nil)) |
| 903 } | 867 } |
| OLD | NEW |