parent
ff95d0aadb
commit
a80457578e
6
Makefile
6
Makefile
|
@ -168,6 +168,12 @@ supervisor: # Compile supervisor binary for production
|
||||||
supervisor-dev: # Compile and watch supervisor binary for development
|
supervisor-dev: # Compile and watch supervisor binary for development
|
||||||
watchexec -w supervisor/src -n -- ./supervisor/compile.bash
|
watchexec -w supervisor/src -n -- ./supervisor/compile.bash
|
||||||
|
|
||||||
|
cli: # Compile cli binary for production
|
||||||
|
./cli/compile.bash
|
||||||
|
|
||||||
|
cli-dev: # Compile and watch cli binary for development
|
||||||
|
watchexec -w cli/src -n -- ./cli/compile.bash
|
||||||
|
|
||||||
server: # Run server for production
|
server: # Run server for production
|
||||||
node backend/server.js
|
node backend/server.js
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
|
||||||
|
set -euo pipefail
|
||||||
|
|
||||||
|
function verbosely {
|
||||||
|
echo "$@"
|
||||||
|
"$@"
|
||||||
|
}
|
||||||
|
|
||||||
|
cd cli
|
||||||
|
mkdir -p build/go out
|
||||||
|
|
||||||
|
export GOCACHE="$PWD/build/go/cache"
|
||||||
|
export GOMODCACHE="$PWD/build/go/mod"
|
||||||
|
|
||||||
|
verbosely go build -o out/riju ./src
|
|
@ -0,0 +1,8 @@
|
||||||
|
module github.com/raxod502/riju/cli
|
||||||
|
|
||||||
|
go 1.16
|
||||||
|
|
||||||
|
require (
|
||||||
|
github.com/alecthomas/kong v0.2.17 // indirect
|
||||||
|
github.com/gorilla/websocket v1.4.2 // indirect
|
||||||
|
)
|
|
@ -0,0 +1,14 @@
|
||||||
|
github.com/alecthomas/kong v0.2.17 h1:URDISCI96MIgcIlQyoCAlhOmrSw6pZScBNkctg8r0W0=
|
||||||
|
github.com/alecthomas/kong v0.2.17/go.mod h1:ka3VZ8GZNPXv9Ov+j4YNLkI8mTuhXyr/0ktSlqIydQQ=
|
||||||
|
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
|
||||||
|
github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc=
|
||||||
|
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||||
|
github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
|
||||||
|
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
|
||||||
|
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
|
||||||
|
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
|
||||||
|
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
|
||||||
|
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
||||||
|
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
|
|
@ -0,0 +1,96 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
// Based in part on
|
||||||
|
// https://github.com/gorilla/websocket/blob/master/examples/echo/client.go
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"log"
|
||||||
|
"net/url"
|
||||||
|
"path"
|
||||||
|
|
||||||
|
"github.com/alecthomas/kong"
|
||||||
|
"github.com/gorilla/websocket"
|
||||||
|
)
|
||||||
|
|
||||||
|
var cli struct {
|
||||||
|
Lang string `arg help:"Name of programming language."`
|
||||||
|
File string `arg optional type:"path" help:"File to run."`
|
||||||
|
Host string `default:"https://riju.codes/api/v1" help:"URL of Riju API."`
|
||||||
|
}
|
||||||
|
|
||||||
|
type message struct {
|
||||||
|
Event string `json:"event"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type terminalInput struct {
|
||||||
|
message
|
||||||
|
Input string `json:"input"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type terminalOutput struct {
|
||||||
|
message
|
||||||
|
Output string `json:"output"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func run() error {
|
||||||
|
apiUrl, err := url.Parse(cli.Host)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
scheme := "wss"
|
||||||
|
if apiUrl.Scheme == "http" {
|
||||||
|
scheme = "ws"
|
||||||
|
}
|
||||||
|
socketUrl := url.URL{
|
||||||
|
Scheme: scheme,
|
||||||
|
Host: apiUrl.Host,
|
||||||
|
Path: path.Join(apiUrl.Path, "ws"),
|
||||||
|
RawQuery: url.Values{
|
||||||
|
"lang": []string{cli.Lang},
|
||||||
|
}.Encode(),
|
||||||
|
}
|
||||||
|
conn, _, err := websocket.DefaultDialer.Dial(socketUrl.String(), nil)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
defer conn.Close()
|
||||||
|
done := make(chan struct{})
|
||||||
|
go func() {
|
||||||
|
defer close(done)
|
||||||
|
for {
|
||||||
|
_, rawMsg, err := conn.ReadMessage()
|
||||||
|
if err != nil {
|
||||||
|
log.Println("failed to read websocket message:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
var genericMsg message
|
||||||
|
if err := json.Unmarshal(rawMsg, &genericMsg); err != nil {
|
||||||
|
log.Println("failed to parse websocket message:", err)
|
||||||
|
}
|
||||||
|
switch genericMsg.Event {
|
||||||
|
case "terminalOutput":
|
||||||
|
var msg terminalOutput
|
||||||
|
if err := json.Unmarshal(rawMsg, &msg); err != nil {
|
||||||
|
log.Println("failed to parse websocket message:", err)
|
||||||
|
}
|
||||||
|
fmt.Print(msg.Output)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
for {
|
||||||
|
select {
|
||||||
|
case <-done:
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
kong.Parse(&cli)
|
||||||
|
if err := run(); err != nil {
|
||||||
|
log.Fatalln(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue