Skip to content

Commit

Permalink
Output formatting (#57)
Browse files Browse the repository at this point in the history
  • Loading branch information
callumevans authored Dec 12, 2024
1 parent a477b23 commit acf8205
Show file tree
Hide file tree
Showing 8 changed files with 169 additions and 65 deletions.
14 changes: 10 additions & 4 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,39 +4,45 @@ go 1.22.5

require (
github.com/BurntSushi/toml v1.4.0
github.com/aws/aws-sdk-go-v2 v1.32.6
github.com/aws/aws-sdk-go-v2/config v1.28.6
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.1
github.com/evanw/esbuild v0.23.0
github.com/fatih/color v1.18.0
github.com/fsnotify/fsnotify v1.7.0
github.com/gorilla/mux v1.8.1
github.com/hashicorp/hcl/v2 v2.21.0
github.com/jedib0t/go-pretty/v6 v6.6.3
github.com/urfave/cli/v2 v2.27.3
github.com/zclconf/go-cty v1.15.0
)

require (
github.com/agext/levenshtein v1.2.3 // indirect
github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect
github.com/aws/aws-sdk-go-v2 v1.32.6 // indirect
github.com/aws/aws-sdk-go-v2/config v1.28.6 // indirect
github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect
github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect
github.com/aws/aws-sdk-go-v2/internal/configsources v1.3.25 // indirect
github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.25 // indirect
github.com/aws/aws-sdk-go-v2/internal/ini v1.8.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.12.1 // indirect
github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.12.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssm v1.56.1 // indirect
github.com/aws/aws-sdk-go-v2/service/sso v1.24.7 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.28.6 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.33.2 // indirect
github.com/aws/smithy-go v1.22.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.4 // indirect
github.com/jmespath/go-jmespath v0.4.0 // indirect
github.com/mattn/go-colorable v0.1.13 // indirect
github.com/mattn/go-isatty v0.0.20 // indirect
github.com/mattn/go-runewidth v0.0.15 // indirect
github.com/mitchellh/go-wordwrap v1.0.1 // indirect
github.com/rivo/uniseg v0.2.0 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 // indirect
golang.org/x/mod v0.20.0 // indirect
golang.org/x/sync v0.8.0 // indirect
golang.org/x/sys v0.24.0 // indirect
golang.org/x/sys v0.25.0 // indirect
golang.org/x/text v0.17.0 // indirect
golang.org/x/tools v0.24.0 // indirect
)
26 changes: 24 additions & 2 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/evanw/esbuild v0.23.0 h1:PLUwTn2pzQfIBRrMKcD3M0g1ALOKIHMDefdFCk7avwM=
github.com/evanw/esbuild v0.23.0/go.mod h1:D2vIQZqV/vIf/VRHtViaUtViZmG7o+kKmlBfVQuRi48=
github.com/fatih/color v1.18.0 h1:S8gINlzdQ840/4pfAwic/ZE0djQEH3wM94VfqLTZcOM=
github.com/fatih/color v1.18.0/go.mod h1:4FelSpRwEGDpQ12mAdzqdOukCy4u8WUtOY6lkT/6HfU=
github.com/fsnotify/fsnotify v1.7.0 h1:8JEhPFa5W2WU7YfeZzPNqzMP6Lwt7L2715Ggo0nosvA=
github.com/fsnotify/fsnotify v1.7.0/go.mod h1:40Bi/Hjc2AVfZrqy+aj+yEI+/bRxZnMJyTJwOpGvigM=
github.com/go-test/deep v1.0.3 h1:ZrJSEWsXzPOxaZnFteGEfooLba+ju3FYIbOrS+rQd68=
Expand All @@ -49,15 +51,30 @@ github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY=
github.com/gorilla/mux v1.8.1/go.mod h1:AKf9I4AEqPTmMytcMc0KkNouC66V3BtZ4qD5fmWSiMQ=
github.com/hashicorp/hcl/v2 v2.21.0 h1:lve4q/o/2rqwYOgUg3y3V2YPyD1/zkCLGjIV74Jit14=
github.com/hashicorp/hcl/v2 v2.21.0/go.mod h1:62ZYHrXgPoX8xBnzl8QzbWq4dyDsDtfCRgIq1rbJEvA=
github.com/jedib0t/go-pretty/v6 v6.6.3 h1:nGqgS0tgIO1Hto47HSaaK4ac/I/Bu7usmdD3qvs0WvM=
github.com/jedib0t/go-pretty/v6 v6.6.3/go.mod h1:zbn98qrYlh95FIhwwsbIip0LYpwSG8SUOScs+v9/t0E=
github.com/jmespath/go-jmespath v0.4.0 h1:BEgLn5cpjn8UN1mAw4NjwDrS35OdebyEtFe+9YPoQUg=
github.com/jmespath/go-jmespath v0.4.0/go.mod h1:T8mJZnbsbmF+m6zOOFylbeCJqk5+pHWvzYPziyZiYoo=
github.com/jmespath/go-jmespath/internal/testify v1.5.1 h1:shLQSRRSCCPj3f2gpwzGwWFoC7ycTf1rcQZHOlsJ6N8=
github.com/jmespath/go-jmespath/internal/testify v1.5.1/go.mod h1:L3OGu8Wl2/fWfCI6z80xFu9LTZmf1ZRjMHUOPmWr69U=
github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA=
github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg=
github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM=
github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY=
github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y=
github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
github.com/mitchellh/go-wordwrap v1.0.1 h1:TLuKupo69TCn6TQSyGxwI1EblZZEsQ0vMlAFQflz0v0=
github.com/mitchellh/go-wordwrap v1.0.1/go.mod h1:R62XHJLzvMFRBbcrT7m7WgmE1eOyTSsCt+hzestvNj0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/rivo/uniseg v0.2.0 h1:S1pD9weZBuJdFmowNwbpi7BJ8TNftyUImj/0WQi72jY=
github.com/rivo/uniseg v0.2.0/go.mod h1:J6wj4VEh+S6ZtnVlnTBMWIodfgj8LQOQFoIToxlJtxc=
github.com/russross/blackfriday/v2 v2.1.0 h1:JIOH55/0cWyOuilr9/qlrm0BSXldqnqwMsf35Ld67mk=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/urfave/cli/v2 v2.27.3 h1:/POWahRmdh7uztQ3CYnaDddk0Rm90PyOgIxgW2rr41M=
github.com/urfave/cli/v2 v2.27.3/go.mod h1:m4QzxcD2qpra4z7WhzEGn74WZLViBnMpb1ToCAKdGRQ=
github.com/xrash/smetrics v0.0.0-20240521201337-686a1a2994c1 h1:gEOO8jv9F4OT7lGCjxCBTO/36wtF6j2nSip77qHd4x4=
Expand All @@ -71,11 +88,16 @@ golang.org/x/mod v0.20.0/go.mod h1:hTbmBsO62+eylJbnUtE2MGJUyE7QWk4xUqPFrRgJ+7c=
golang.org/x/sync v0.8.0 h1:3NFvSEYkUoMifnESzZl15y791HH1qU2xm6eCJU5ZPXQ=
golang.org/x/sync v0.8.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.24.0 h1:Twjiwq9dn6R1fQcyiK+wQyHWfaz/BJB+YIpzU/Cv3Xg=
golang.org/x/sys v0.24.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34=
golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/text v0.17.0 h1:XtiM5bkSOt+ewxlOE/aE/AKEHibwj/6gvWMl9Rsh0Qc=
golang.org/x/text v0.17.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY=
golang.org/x/tools v0.24.0 h1:J1shsA93PJUEVaUSaay7UXAyE8aimq3GW0pjlolpa24=
golang.org/x/tools v0.24.0/go.mod h1:YhNqVBIfWHdzvTLs0d8LCuMhkKUgSUKldakyV7W/WDQ=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/yaml.v2 v2.2.8 h1:obN1ZagJSUGI0Ek/LBmuj4SNLPfIny3KsKFopxRdj10=
gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
103 changes: 71 additions & 32 deletions offline/handler_server.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,17 @@ package offline

import (
"bufio"
"context"
"encoding/json"
"fmt"
"io"
"net/http"
"os"
"strings"
"sync"
"time"

"github.com/fatih/color"
"github.com/gorilla/mux"
)

Expand All @@ -28,68 +31,104 @@ func ServeHandler(handlerInstance *HandlerInstance, r *mux.Router) {
defer np.Close()

for method, path := range handlerInstance.handlerConfig.Http {
// TODO: Emulate API Gateway's 404 for missing routes / methods

go r.HandleFunc(path, func(w http.ResponseWriter, r *http.Request) {
handlerExecutionMutex.Lock()
defer handlerExecutionMutex.Unlock()

ctx, cancel := context.WithTimeout(r.Context(), 30*time.Second)
defer cancel()

code := generateHandlerRuntimeCode(handlerInstance, r)

go np.Execute(code)
np.Execute(code)

parsedOutputChan := make(chan *struct {
handlerResult *handlerResult
err error
}, 1)

fmt.Printf("%s %s (%s) \n", r.Method, r.URL.Path, handlerInstance.handlerConfig.Name)
start := time.Now()

// stdout processing
go func() {
scanner := bufio.NewReader(np.stdout)

for {
line, _ := scanner.ReadString('\n')
select {
case <-ctx.Done():
return
default:
line, _ := scanner.ReadString('\n')

if strings.HasPrefix(line, "TERRABLE_RESULT_START") {
extractedResult, err := extractResult(line)

if strings.HasPrefix(line, "TERRABLE_RESULT_START") {
extractedResult, err := extractResult(line)
parsedOutputChan <- &struct {
handlerResult *handlerResult
err error
}{
handlerResult: extractedResult,
err: err,
}

parsedOutputChan <- &struct {
handlerResult *handlerResult
err error
}{
handlerResult: extractedResult,
err: err,
return
}

return
}
if strings.HasPrefix(line, "CODE_EXECUTION_COMPLETE") {
continue
}

if strings.HasPrefix(line, "CODE_EXECUTION_COMPLETE") {
continue
fmt.Println(line)
}
}
}()

// stderr processing
go func() {
scanner := bufio.NewReader(np.stderr)
errorColour := color.New(color.FgHiRed).SprintFunc()

fmt.Println(line)
for {
select {
case <-ctx.Done():
return
default:
line, _ := scanner.ReadString('\n')
fmt.Println(errorColour(line))
}
}
}()

parsed := <-parsedOutputChan
select {
case parsed := <-parsedOutputChan:
if parsed.err != nil {
fmt.Println(err)
w.WriteHeader(500)
w.Write([]byte{})
return
}

if parsed.err != nil {
fmt.Println(err)
w.WriteHeader(500)
w.Write([]byte{})
return
}
// Set response headers
for k, header := range parsed.handlerResult.Headers {
w.Header().Set(k, header)
}

// Set response headers
for k, header := range parsed.handlerResult.Headers {
w.Header().Set(k, header)
}
// Write status code
w.WriteHeader(int(parsed.handlerResult.StatusCode))

// Write status code
w.WriteHeader(int(parsed.handlerResult.StatusCode))
// Write the body
w.Write([]byte(parsed.handlerResult.Body))
fmt.Printf("Completed in %.dms\n\n", time.Since(start).Milliseconds())
case <-ctx.Done():
// Handle timeout
w.WriteHeader(http.StatusGatewayTimeout)
w.Write([]byte{})

// Write the body
w.Write([]byte(parsed.handlerResult.Body))
fmt.Printf("Request timed out\n")
fmt.Printf("Completed in %.dms\n\n", time.Since(start).Milliseconds())
return
}
}).Methods(method)
}

Expand Down
54 changes: 45 additions & 9 deletions offline/offline.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,12 @@ import (
"log"
"net"
"net/http"
"strings"
"os"
"sync"

"github.com/fatih/color"
"github.com/gorilla/mux"
"github.com/jedib0t/go-pretty/v6/table"
"github.com/terrable-dev/terrable/config"
"github.com/terrable-dev/terrable/utils"
)
Expand Down Expand Up @@ -41,6 +43,12 @@ func Run(filePath string, moduleName string, port string) error {

r := mux.NewRouter()

// 404 for not found
r.MethodNotAllowedHandler = http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "text/plain; charset=utf-8")
w.WriteHeader(http.StatusNotFound)
})

// Start compiling and serving each handler
for _, handler := range terrableConfig.Handlers {
wg.Add(1)
Expand All @@ -55,8 +63,6 @@ func Run(filePath string, moduleName string, port string) error {
}(handler)
}

fmt.Printf("Starting server on :%d\n", activePort)

server := &http.Server{
Handler: r,
}
Expand Down Expand Up @@ -94,18 +100,48 @@ func getListener(port string) (net.Listener, int, error) {

func printConfig(config config.TerrableConfig, port int) {
totalEndpoints := 0
printlines := []string{}
t := table.NewWriter()

t.SetOutputMirror(os.Stdout)

for _, handler := range config.Handlers {
for method, path := range handler.Http {
totalEndpoints += 1
printlines = append(printlines, fmt.Sprintf(" %-*s http://localhost:%d%s\n", 5, method, port, path))
totalEndpoints++
methodColor := color.New(color.FgHiBlue).SprintFunc()
hostColor := color.New(color.FgHiBlack).SprintFunc()
pathColor := color.New(color.FgHiGreen).SprintFunc()
handlerNameColor := color.New(color.FgHiBlack).SprintFunc()

url := fmt.Sprintf("%s%s",
hostColor(fmt.Sprintf("http://localhost:%d", port)),
pathColor(path))

t.AppendRow(table.Row{
methodColor(method),
url,
handlerNameColor(fmt.Sprintf("(%s)", handler.Name)),
})
}
}

fmt.Printf("Starting terrable local server... \n")
fmt.Printf("%d Endpoint(s) to prepare...\n", totalEndpoints)
fmt.Print(strings.Join(printlines, ""))
color.New(color.FgHiGreen, color.Bold).Println("Starting terrable local server...")

endpointMessage := "Endpoint to prepare..."

if totalEndpoints != 1 {
endpointMessage = "Endpoints to prepare..."
}

color.New(color.FgHiBlue, color.Bold).Printf("%d %s\n\n", totalEndpoints, endpointMessage)

t.SetStyle(table.StyleLight)
t.Style().Options.DrawBorder = false
t.Style().Options.SeparateColumns = false
t.Style().Options.SeparateHeader = false

t.Render()

color.New(color.FgHiGreen, color.Bold).Printf("\nServer started on :%d\n\n", port)
}

func mergeEnvMaps(global, local map[string]string) map[string]string {
Expand Down
Loading

0 comments on commit acf8205

Please sign in to comment.