Skip to content

Commit

Permalink
Merge branch 'release/v0.9.0'
Browse files Browse the repository at this point in the history
  • Loading branch information
cfoust committed Aug 21, 2024
2 parents 5568b6e + 122a6fc commit 4f71db9
Show file tree
Hide file tree
Showing 53 changed files with 2,184 additions and 322 deletions.
16 changes: 10 additions & 6 deletions cmd/cy/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,12 +137,12 @@ func poll(conn Connection) error {
}

go func() {
events := conn.Receive()
events := conn.Subscribe(conn.Ctx())
for {
select {
case <-conn.Ctx().Done():
return
case packet := <-events:
case packet := <-events.Recv():
if packet.Error != nil {
// TODO(cfoust): 12/25/23
return
Expand All @@ -167,17 +167,21 @@ func poll(conn Connection) error {
)
}

func connect(socketPath string) (Connection, error) {
func connect(socketPath string, shouldStart bool) (Connection, error) {
// mimics client_connect() in tmux's client.c
var lockFd *os.File
var lockPath string

locked := false
started := false
for {
conn, err := ws.Connect(context.Background(), P.Protocol, socketPath)
if err == nil {
return conn, nil
conn, err := ws.Connect(
context.Background(),
P.Protocol,
socketPath,
)
if err == nil || !shouldStart {
return conn, err
}

message := err.Error()
Expand Down
105 changes: 105 additions & 0 deletions cmd/cy/connect.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package main

import (
"fmt"
"net/http"
"os"
"runtime/pprof"
"runtime/trace"

"github.com/rs/zerolog/log"
"github.com/sevlyar/go-daemon"
)

// connectCommand is the entrypoint for the connect command.
func connectCommand() error {
var socketPath string

label, err := getSocketPath(CLI.Socket)
if err != nil {
return fmt.Errorf(
"failed to detect socket path: %s",
err,
)
}
socketPath = label

if daemon.WasReborn() {
cntx := new(daemon.Context)
_, err := cntx.Reborn()
if err != nil {
return fmt.Errorf("failed to reincarnate")
}

defer func() {
if err := cntx.Release(); err != nil {
log.Panic().Err(err).Msg("unable to release pid-file")
}
}()

if len(CLI.Connect.CPU) > 0 {
f, err := os.Create(CLI.Connect.CPU)
if err != nil {
return fmt.Errorf(
"unable to create %s: %s",
CLI.Connect.CPU,
err,
)
}
defer f.Close()
if err := pprof.StartCPUProfile(f); err != nil {
return fmt.Errorf(
"could not start CPU profile: %s",
err,
)
}
defer pprof.StopCPUProfile()
}

if len(CLI.Connect.Trace) > 0 {
f, err := os.Create(CLI.Connect.Trace)
if err != nil {
return fmt.Errorf(
"unable to create %s: %s",
CLI.Connect.Trace,
err,
)
}
defer f.Close()
if err := trace.Start(f); err != nil {
return fmt.Errorf(
"could not start trace profile: %s",
err,
)
}
defer trace.Stop()
}

err = serve(socketPath)
if err != nil && err != http.ErrServerClosed {
return fmt.Errorf(
"failed to start cy: %s",
err,
)
}
return nil
}

conn, err := connect(socketPath, true)
if err != nil {
return fmt.Errorf(
"failed to start cy: %s",
err,
)
}

err = poll(conn)
if err != nil {
return fmt.Errorf(
"failed while polling: %s",
err,
)
}

return nil
}
103 changes: 103 additions & 0 deletions cmd/cy/exec.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
package main

import (
"fmt"
"io/ioutil"
"os"
"strconv"

"github.com/cfoust/cy/pkg/cy"
)

func getContext() (socket string, id int, ok bool) {
context, ok := os.LookupEnv(cy.CONTEXT_ENV)
if !ok {
return "", 0, false
}

match := cy.CONTEXT_REGEX.FindStringSubmatch(context)
if match == nil {
return "", 0, false
}

socket = match[cy.CONTEXT_REGEX.SubexpIndex("socket")]
id, _ = strconv.Atoi(match[cy.CONTEXT_REGEX.SubexpIndex("id")])
ok = true
return
}

// execCommand is the entrypoint for the exec command.
func execCommand() error {
if CLI.Exec.Command == "" && CLI.Exec.File == "" {
return fmt.Errorf("no Janet code provided")
}

var err error
var source string
var code []byte

if CLI.Exec.Command != "" {
source = "<unknown>"
code = []byte(CLI.Exec.Command)
} else if CLI.Exec.File == "-" {
source = "<stdin>"
code, err = ioutil.ReadAll(os.Stdin)
if err != nil {
return fmt.Errorf("failed to read from stdin: %s", err)
}
} else {
source = CLI.Exec.File
code, err = ioutil.ReadFile(CLI.Exec.File)
if err != nil {
return fmt.Errorf("failed to read from %s: %s", CLI.Exec.File, err)
}
}

socket, id, ok := getContext()
if !ok {
socket = CLI.Socket
}

socketPath, err := getSocketPath(socket)
if err != nil {
return err
}

var conn Connection
conn, err = connect(socketPath, false)
if err != nil {
return err
}

format := OutputFormatRaw
switch CLI.Exec.Format {
case "raw":
format = OutputFormatRaw
case "json":
format = OutputFormatJSON
case "janet":
format = OutputFormatJanet
default:
return fmt.Errorf(
"unknown output format: %s",
CLI.Exec.Format,
)
}

response, err := RPC[RPCExecArgs, RPCExecResponse](
conn,
RPCExec,
RPCExecArgs{
Source: source,
Code: code,
Node: id,
Format: format,
},
)
if err != nil || len(response.Data) == 0 {
return err
}

_, err = os.Stdout.Write(response.Data)
return err
}
Loading

0 comments on commit 4f71db9

Please sign in to comment.