Skip to content

Commit

Permalink
feat: Add LSP
Browse files Browse the repository at this point in the history
Signed-off-by: Ce Gao <cegao@tensorchord.ai>
  • Loading branch information
gaocegege committed Jun 16, 2022
1 parent 23f8a40 commit 62fd9bd
Show file tree
Hide file tree
Showing 10 changed files with 468 additions and 2 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@
ROOT := github.com/tensorchord/envd

# Target binaries. You can build multiple binaries for a single project.
TARGETS := envd envd-ssh
TARGETS := envd envd-ssh envd-lsp

# Container image prefix and suffix added to targets.
# The final built images are:
Expand Down
104 changes: 104 additions & 0 deletions cmd/envd-lsp/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
// Copyright 2022 The envd Authors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package main

import (
"fmt"
"os"

"github.com/tensorchord/envd/pkg/lang/lsp"
"github.com/tensorchord/envd/pkg/version"
cli "github.com/urfave/cli/v2"
"go.lsp.dev/protocol"
"go.uber.org/zap"
"go.uber.org/zap/zapcore"
)

// go lsp server uses zap, thus we have to keep two loggers (logrus and zap) in envd.
// zap is only used in lsp subcommand.
var logLevel = zap.NewAtomicLevelAt(zapcore.WarnLevel)

func startLSP(clicontext *cli.Context) error {
logger, cleanup := newzapLogger()
defer cleanup()
ctx := protocol.WithLogger(clicontext.Context, logger)

s := lsp.New()
err := s.Start(ctx, clicontext.String("address"))
return err
}

func newzapLogger() (logger *zap.Logger, cleanup func()) {
cfg := zap.NewDevelopmentConfig()
cfg.Level = logLevel
cfg.Development = false
logger, err := cfg.Build()
if err != nil {
panic(fmt.Errorf("failed to initialize logger: %v", err))
}

cleanup = func() {
_ = logger.Sync()
}
return logger, cleanup
}

func main() {
cli.VersionPrinter = func(c *cli.Context) {
fmt.Println(c.App.Name, version.Package, version.GetVersion().String())
}

app := cli.NewApp()
app.Name = "envd-lsp"
app.Usage = "language server for envd"
app.Version = version.GetVersion().String()
app.Flags = []cli.Flag{
&cli.StringFlag{
Name: "address",
Usage: "Address (hostname:port) to listen on",
},
&cli.BoolFlag{
Name: "debug",
Usage: "Enable debug logging",
},
}

// Deal with debug flag.
var debugEnabled bool

app.Before = func(context *cli.Context) error {
debugEnabled = context.Bool("debug")

if debugEnabled {
logLevel.SetLevel(zapcore.DebugLevel)
}
return nil
}

app.Action = startLSP
handleErr(debugEnabled, app.Run(os.Args))
}

func handleErr(debug bool, err error) {
if err == nil {
return
}
if debug {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
} else {
fmt.Fprintf(os.Stderr, "error: %v\n", err)
}
os.Exit(1)
}
3 changes: 3 additions & 0 deletions envd/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,3 +12,6 @@
# See the License for the specific language governing permissions and
# limitations under the License.

# Our documentation generation framework doesn't properly handle __file__,
# so we call it __file__ and edit it later.
file__: str = ""
54 changes: 54 additions & 0 deletions envd/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
package envd

import (
"bytes"
"embed"
"fmt"
"io/fs"
"os"
"path/filepath"
)

//go:embed api/*.py api/**/*.py
var api embed.FS

const autoGeneratedHeader = `### AUTO-GENERATED ###
# To make changes, modify the following file in the Tilt repository:
# envd/%s
`

func ApiStubs() fs.FS {
f, err := fs.Sub(api, "api")
if err != nil {
panic(err)
}
return f
}

func WalkApiStubs(fn fs.WalkDirFunc) error {
return fs.WalkDir(api, "api", fn)
}

func DumpApiStubs(dir string, callback func(string, error)) error {
return WalkApiStubs(func(path string, d fs.DirEntry, e error) error {
if e != nil {
return e
}
var err error
dest := filepath.Join(dir, path)
if d.IsDir() {
err = os.MkdirAll(dest, 0755)
} else {
buf := bytes.NewBufferString(fmt.Sprintf(autoGeneratedHeader, path))
var bytes []byte
bytes, err = api.ReadFile(path)
if err != nil {
return err
}
buf.Write(bytes)
err = os.WriteFile(dest, buf.Bytes(), 0644)
}
callback(path, err)
return err
})
}
1 change: 0 additions & 1 deletion envd/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,4 +11,3 @@
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

File renamed without changes.
File renamed without changes.
11 changes: 11 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -29,10 +29,14 @@ require (
github.com/sirupsen/logrus v1.8.1
github.com/spf13/viper v1.4.0
github.com/stretchr/testify v1.7.2
github.com/tilt-dev/starlark-lsp v0.0.0-20220517144608-76df2b44bc8a
github.com/tonistiigi/units v0.0.0-20180711220420-6950e57a87ea
github.com/tonistiigi/vt100 v0.0.0-20210615222946-8066bb97264f
github.com/urfave/cli/v2 v2.8.1
go.lsp.dev/jsonrpc2 v0.9.0
go.lsp.dev/protocol v0.11.2
go.starlark.net v0.0.0-20220328144851-d1966c6b9fcd
go.uber.org/zap v1.20.0
golang.org/x/crypto v0.0.0-20211215153901-e495a2d5b3d3
golang.org/x/sync v0.0.0-20210220032951-036812b2e83c
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211
Expand All @@ -56,6 +60,7 @@ require (
github.com/docker/cli v20.10.13+incompatible // indirect
github.com/docker/distribution v2.8.1+incompatible // indirect
github.com/emirpasic/gods v1.12.0 // indirect
github.com/francoispqt/gojay v1.2.13 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/getsentry/sentry-go v0.12.0 // indirect
github.com/go-git/gcfg v1.5.0 // indirect
Expand Down Expand Up @@ -87,20 +92,26 @@ require (
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/rogpeppe/go-internal v1.8.1 // indirect
github.com/russross/blackfriday/v2 v2.1.0 // indirect
github.com/segmentio/encoding v0.2.7 // indirect
github.com/sergi/go-diff v1.1.0 // indirect
github.com/smacker/go-tree-sitter v0.0.0-20220209044044-0d3022e933c3 // indirect
github.com/spf13/afero v1.1.2 // indirect
github.com/spf13/cast v1.3.0 // indirect
github.com/spf13/jwalterweatherman v1.0.0 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/tonistiigi/fsutil v0.0.0-20220115021204-b19f7f9cb274 // indirect
github.com/xanzy/ssh-agent v0.3.0 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
go.lsp.dev/pkg v0.0.0-20210323044036-f7deec69b52e // indirect
go.lsp.dev/uri v0.3.0 // indirect
go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.29.0 // indirect
go.opentelemetry.io/otel v1.4.1 // indirect
go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.4.1 // indirect
go.opentelemetry.io/otel/sdk v1.4.1 // indirect
go.opentelemetry.io/otel/trace v1.4.1 // indirect
go.opentelemetry.io/proto/otlp v0.12.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.7.0 // indirect
golang.org/x/net v0.0.0-20220225172249-27dd8689420f // indirect
golang.org/x/sys v0.0.0-20220422013727-9388b58f7150 // indirect
golang.org/x/text v0.3.7 // indirect
Expand Down
Loading

0 comments on commit 62fd9bd

Please sign in to comment.