Philipp Schrader | d9096a3 | 2022-02-24 17:53:09 -0800 | [diff] [blame^] | 1 | // This binary lets users interact with the scouting web server in order to |
| 2 | // debug it. Run with `--help` to see all the options. |
| 3 | |
| 4 | package main |
| 5 | |
| 6 | import ( |
| 7 | "flag" |
| 8 | "io/ioutil" |
| 9 | "log" |
| 10 | "os" |
| 11 | "os/exec" |
| 12 | "path/filepath" |
| 13 | |
| 14 | "github.com/frc971/971-Robot-Code/scouting/webserver/requests/debug" |
| 15 | ) |
| 16 | |
| 17 | // Returns the absolute path of the specified path. This is an unwrapped |
| 18 | // version of `filepath.Abs`. |
| 19 | func absPath(path string) string { |
| 20 | result, err := filepath.Abs(path) |
| 21 | if err != nil { |
| 22 | log.Fatal("Failed to determine absolute path for ", path, ": ", err) |
| 23 | } |
| 24 | return result |
| 25 | } |
| 26 | |
| 27 | // Parses the specified JSON file into a binary version (i.e. serialized |
| 28 | // flatbuffer). This uses the `flatc` binary and the JSON's corresponding |
| 29 | // `.fbs` file. |
| 30 | func parseJson(fbsPath string, jsonPath string) []byte { |
| 31 | // Work inside a temporary directory since `flatc` doesn't allow us to |
| 32 | // customize the name of the output file. |
| 33 | dir, err := ioutil.TempDir("", "webserver_debug_cli") |
| 34 | if err != nil { |
| 35 | log.Fatal("Failed to create temporary directory: ", err) |
| 36 | } |
| 37 | defer os.RemoveAll(dir) |
| 38 | |
| 39 | // Turn these paths absolute so that it everything still works from |
| 40 | // inside the temporary directory. |
| 41 | absFlatcPath := absPath("external/com_github_google_flatbuffers/flatc") |
| 42 | absFbsPath := absPath(fbsPath) |
| 43 | |
| 44 | // Create a symlink to the .fbs file so that the output filename that |
| 45 | // `flatc` generates is predictable. I.e. `fb.json` gets serialized |
| 46 | // into `fb.bin`. |
| 47 | jsonSymlink := filepath.Join(dir, "fb.json") |
| 48 | os.Symlink(jsonPath, jsonSymlink) |
| 49 | |
| 50 | // Execute the `flatc` command. |
| 51 | flatcCommand := exec.Command(absFlatcPath, "--binary", absFbsPath, jsonSymlink) |
| 52 | flatcCommand.Dir = dir |
| 53 | err = flatcCommand.Run() |
| 54 | if err != nil { |
| 55 | log.Fatal("Failed to execute flatc: ", err) |
| 56 | } |
| 57 | |
| 58 | // Read the serialized flatbuffer and return it. |
| 59 | binaryPath := filepath.Join(dir, "fb.bin") |
| 60 | binaryFb, err := os.ReadFile(binaryPath) |
| 61 | if err != nil { |
| 62 | log.Fatal("Failed to read flatc output ", binaryPath, ": ", err) |
| 63 | } |
| 64 | return binaryFb |
| 65 | } |
| 66 | |
| 67 | func main() { |
| 68 | // Parse command line arguments. |
| 69 | addressPtr := flag.String("address", "http://localhost:8080", |
| 70 | "The end point where the server is listening.") |
| 71 | submitDataScoutingPtr := flag.String("submitDataScouting", "", |
| 72 | "If specified, parse the file as a SubmitDataScouting JSON request.") |
| 73 | flag.Parse() |
| 74 | |
| 75 | // Handle the actual arguments. |
| 76 | if *submitDataScoutingPtr != "" { |
| 77 | log.Printf("Sending SubmitDataScouting to %s", *addressPtr) |
| 78 | binaryRequest := parseJson( |
| 79 | "scouting/webserver/requests/messages/submit_data_scouting.fbs", |
| 80 | *submitDataScoutingPtr) |
| 81 | response, err := debug.SubmitDataScouting(*addressPtr, binaryRequest) |
| 82 | if err != nil { |
| 83 | log.Fatal("Failed SubmitDataScouting: ", err) |
| 84 | } |
| 85 | log.Printf("%+v", response) |
| 86 | } |
| 87 | } |