Skip to content

Commit 408c6ce

Browse files
vigneshd332shubham-1806Ashwin125
authored
feat: jsonrpc integration & cpp autocomplete (#5)
* feat: add player code submodule * feat: Symlinks and refactoring * feat[WIP]: Integrate JSONRPC * Feat : Integrate ccls language server * fix: pre commit * Refactor : Improve readability * Fix : send both file and folder path * refactor: readablity * update: submodule * fix: removed unnecessary variables/checks --------- Co-authored-by: shubham-1806 <shub.agarwal2003@gmail.com> Co-authored-by: Ashwani <ashwinvishwakarma125@gmail.com>
1 parent 0e49fc1 commit 408c6ce

File tree

20 files changed

+280
-117
lines changed

20 files changed

+280
-117
lines changed

.env.example

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
TARGET=dev
22
SERVER_PORT=8000
3+
FRONTEND_URL=http://localhost:3000

.githooks/pre-commit

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,13 +5,14 @@ echo "\033[36m
55
Running golangci-lint
66
======================================================================"
77

8-
golangci-lint run . --config .golangci.yaml
8+
golangci-lint run --config .golangci.yaml
99

1010
if [ $? != 0 ]; then
1111
echo "\033[31m
1212
======================================================================
1313
golangci-lint check failed
1414
======================================================================"
15+
exit 1
1516
else
1617
echo "\033[32m
1718
======================================================================

.gitmodules

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
[submodule "player_code"]
2+
path = player_code
3+
url = https://github.com/delta/codecharacter-default-codes-2022.git

Dockerfile

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
1+
## Base
2+
FROM golang:1.18-alpine AS base
3+
4+
RUN apk add --no-cache build-base ccls py3-lsp-server
5+
16
## Build
2-
FROM golang:1.18-alpine AS build
7+
FROM base AS build
38

49
WORKDIR /app
510

@@ -15,7 +20,7 @@ FROM build AS dev
1520

1621
WORKDIR /app
1722

18-
RUN apk add --no-cache make ccls
23+
RUN apk add --no-cache make
1924

2025
RUN go install github.com/cespare/reflex@latest
2126

@@ -24,7 +29,7 @@ CMD ["make watch"]
2429

2530

2631
## Prod
27-
FROM alpine:latest AS prod
32+
FROM base AS prod
2833

2934
WORKDIR /
3035

config/environment.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
)
1111

1212
var ServerPort string
13+
var FrontendURL string
1314

1415
func InitConfig() {
1516
err := godotenv.Load()
@@ -18,4 +19,5 @@ func InitConfig() {
1819
}
1920

2021
ServerPort = os.Getenv("SERVER_PORT")
22+
FrontendURL = os.Getenv("FRONTEND_URL")
2123
}

controllers/file.go

Lines changed: 13 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,25 @@
11
package controllers
22

33
import (
4-
"fmt"
54
"io/ioutil"
5+
"path/filepath"
66

77
"github.com/delta/codecharacter-lsp-2023/models"
88
)
99

1010
func handleFileUpdate(message map[string]interface{}, ws *models.WebsocketConnection) error {
11-
fmt.Println("Processing File Update Request")
12-
var filename string
13-
switch ws.Language {
14-
case "cpp":
15-
filename = "run.cpp"
16-
case "java":
17-
filename = "run.java"
18-
case "python":
19-
filename = "run.py"
20-
}
21-
err := ioutil.WriteFile(ws.WorkspacePath+"/"+filename, []byte(message["code"].(string)), 0644)
11+
filename := "player" + ws.Language.GetExtension()
12+
return ioutil.WriteFile(ws.WorkspacePath+"/"+filename, []byte(message["code"].(string)), 0644)
13+
}
14+
15+
func getAbsPath(ws *models.WebsocketConnection) error {
16+
absFolderPath, err := filepath.Abs(ws.WorkspacePath)
17+
responseBody := make(map[string]interface{})
2218
if err != nil {
23-
fmt.Println(err)
24-
return err
19+
return SendErrorMessage(ws, err)
2520
}
26-
return nil
21+
responseBody["status"] = "success"
22+
responseBody["folderpath"] = absFolderPath
23+
responseBody["filepath"] = absFolderPath + "/player" + ws.Language.GetExtension()
24+
return SendMessage(ws, responseBody)
2725
}

controllers/jsonrpc.go

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package controllers
2+
3+
import (
4+
"bufio"
5+
"encoding/json"
6+
"fmt"
7+
"strconv"
8+
"strings"
9+
10+
"github.com/delta/codecharacter-lsp-2023/models"
11+
)
12+
13+
func StreamReader(ws *models.WebsocketConnection) {
14+
if ws.LSPServer.Process == nil {
15+
return
16+
}
17+
for {
18+
var responseMessageBytes []byte
19+
reader := bufio.NewReader(ws.LSPServer.Stdout)
20+
contentLengthLine, err := reader.ReadBytes('\n')
21+
var contentLengthHeader string
22+
contentLengthHeader = string(contentLengthLine)
23+
if err != nil {
24+
if err.Error() == "EOF" {
25+
return
26+
}
27+
continue
28+
}
29+
const prefix = "Content-Length: "
30+
const suffix = "\r\n"
31+
contentLengthHeader = strings.TrimPrefix(contentLengthHeader, prefix)
32+
contentLengthHeader = strings.TrimSuffix(contentLengthHeader, suffix)
33+
contentLength, err := strconv.Atoi(contentLengthHeader)
34+
if err != nil {
35+
continue
36+
}
37+
_, err = reader.ReadBytes('\n')
38+
if err != nil {
39+
continue
40+
}
41+
for i := 0; i < contentLength; i++ {
42+
currbyte, err := reader.ReadByte()
43+
if err != nil {
44+
continue
45+
}
46+
responseMessageBytes = append(responseMessageBytes, currbyte)
47+
}
48+
var responseMessage map[string]interface{}
49+
err = json.Unmarshal(responseMessageBytes, &responseMessage)
50+
if err != nil {
51+
continue
52+
}
53+
_ = SendMessage(ws, responseMessage)
54+
}
55+
}
56+
57+
func handleJSONRPC(ws *models.WebsocketConnection, requestMessageBytes []byte) error {
58+
contentLength := len(requestMessageBytes)
59+
header := fmt.Sprintf("Content-Length: %d\n\n", contentLength)
60+
requestMessage := header + string(requestMessageBytes)
61+
_, err := ws.LSPServer.Stdin.Write([]byte(requestMessage))
62+
return err
63+
}

controllers/message.go

Lines changed: 13 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ package controllers
22

33
import (
44
"encoding/json"
5-
"fmt"
65

76
"github.com/delta/codecharacter-lsp-2023/models"
87
"github.com/gorilla/websocket"
@@ -15,7 +14,6 @@ func HandleMessage(ws *models.WebsocketConnection, messageBytes []byte) error {
1514
return err
1615
}
1716
_, isPresent := message["jsonrpc"]
18-
fmt.Println("Is JSONRPC? : ", isPresent)
1917
if isPresent {
2018
return handleJSONRPCRequest(ws, messageBytes)
2119
}
@@ -27,22 +25,26 @@ func SendMessage(ws *models.WebsocketConnection, message map[string]interface{})
2725
if err != nil {
2826
return err
2927
}
30-
err = ws.Connection.WriteMessage(websocket.TextMessage, messageBytes)
31-
if err != nil {
32-
return err
33-
}
34-
return nil
28+
return ws.Connection.WriteMessage(websocket.TextMessage, messageBytes)
29+
}
30+
31+
func SendErrorMessage(ws *models.WebsocketConnection, message error) error {
32+
responseBody := make(map[string]interface{})
33+
responseBody["status"] = "error"
34+
responseBody["message"] = message.Error()
35+
return SendMessage(ws, responseBody)
3536
}
3637

3738
func handleJSONRPCRequest(ws *models.WebsocketConnection, messageBytes []byte) error {
38-
fmt.Println("JSONRPC Request : ", string(messageBytes), " with ID : ", ws.ID)
39-
return nil
39+
return handleJSONRPC(ws, messageBytes)
4040
}
4141

4242
func handleWebSocketRequest(ws *models.WebsocketConnection, message map[string]interface{}) error {
43-
fmt.Println("Websocket Request : ", message, " with ID : ", ws.ID)
44-
if message["operation"] == "fileUpdate" {
43+
switch message["operation"] {
44+
case "fileUpdate":
4545
return handleFileUpdate(message, ws)
46+
case "getAbsPath":
47+
return getAbsPath(ws)
4648
}
4749
return nil
4850
}

go.mod

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,7 @@ require (
66
github.com/fatih/color v1.13.0
77
github.com/joho/godotenv v1.4.0
88
github.com/labstack/echo/v4 v4.9.0
9-
)
10-
11-
require github.com/gorilla/websocket v1.5.0
12-
13-
require (
9+
github.com/gorilla/websocket v1.5.0
1410
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
1511
github.com/google/uuid v1.3.0
1612
github.com/labstack/gommon v0.4.0 // indirect

main.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,11 @@ func main() {
1313

1414
server := echo.New()
1515
utils.InitLogger(server)
16-
server.Use(middleware.CORS())
1716
config.InitConfig()
17+
server.Use(middleware.CORSWithConfig(middleware.CORSConfig{
18+
AllowOrigins: []string{config.FrontendURL},
19+
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
20+
}))
1821
router.InitRoutes(server)
1922

2023
server.Logger.Fatal(server.Start(":" + config.ServerPort))

0 commit comments

Comments
 (0)