Skip to content
This repository was archived by the owner on Mar 8, 2020. It is now read-only.

Commit 9b89878

Browse files
Denys Smirnovdennwc
authored andcommitted
protocol: define supported languages endpoint; add language aliases
Signed-off-by: Denys Smirnov <[email protected]>
1 parent 2a9411f commit 9b89878

File tree

12 files changed

+1494
-133
lines changed

12 files changed

+1494
-133
lines changed

build/build.go

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -257,9 +257,7 @@ func (d *Driver) FillManifest(dest string) error {
257257
return err
258258
}
259259
m.Version = vers
260-
261-
now := time.Now().UTC()
262-
m.Build = &now
260+
m.Build = time.Now().UTC()
263261

264262
bm, err := d.readBuildManifest()
265263
if err != nil {

build/build_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import (
1313
"google.golang.org/grpc"
1414

1515
"github.com/bblfsh/sdk/v3/driver"
16+
"github.com/bblfsh/sdk/v3/driver/manifest"
1617
"github.com/bblfsh/sdk/v3/internal/docker"
1718
"github.com/bblfsh/sdk/v3/protocol"
1819
"github.com/bblfsh/sdk/v3/uast/nodes"
@@ -155,3 +156,11 @@ func (d *dockerDriver) Close() error {
155156
func (d *dockerDriver) Parse(ctx context.Context, src string, opts *driver.ParseOptions) (nodes.Node, error) {
156157
return d.d.Parse(ctx, src, opts)
157158
}
159+
160+
func (d *dockerDriver) Version(ctx context.Context) (driver.Version, error) {
161+
return d.d.Version(ctx)
162+
}
163+
164+
func (d *dockerDriver) Languages(ctx context.Context) ([]manifest.Manifest, error) {
165+
return d.d.Languages(ctx)
166+
}

driver/driver.go

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ package driver
44
import (
55
"context"
66
"fmt"
7+
"time"
78

89
"gopkg.in/src-d/go-errors.v1"
910

@@ -27,6 +28,11 @@ var (
2728
ErrModeNotSupported = errors.NewKind("transform mode not supported")
2829
)
2930

31+
const (
32+
// ManifestLocation is the path of the manifest file in the driver image.
33+
ManifestLocation = "/opt/driver/etc/" + manifest.Filename
34+
)
35+
3036
// ErrMulti joins multiple errors.
3137
type ErrMulti = derrors.ErrMulti
3238

@@ -87,13 +93,24 @@ type Driver interface {
8793
// Native driver failures are indicated by ErrDriverFailure and UAST transformation are indicated by ErrTransformFailure.
8894
// All other errors indicate a protocol or server failure.
8995
Parse(ctx context.Context, src string, opts *ParseOptions) (nodes.Node, error)
96+
97+
// Version returns a version of the driver or the server, depending where is this interface is implemented.
98+
Version(ctx context.Context) (Version, error)
99+
100+
// Languages returns a list of manifests for languages supported by this driver or the server.
101+
Languages(ctx context.Context) ([]manifest.Manifest, error)
102+
}
103+
104+
// Version information for driver or the server.
105+
type Version struct {
106+
Version string // the version label for the driver, e.g., 'v1.2.3-tag' or 'undefined'
107+
Build time.Time // the timestamp when the driver was built
90108
}
91109

92110
// DriverModule is an interface for a driver instance.
93111
type DriverModule interface {
94112
Module
95113
Driver
96-
Manifest() (manifest.Manifest, error)
97114
}
98115

99116
// Native is a base interface of a language driver that returns a native AST.

driver/impl.go

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,15 @@ func (d *driverImpl) Parse(rctx context.Context, src string, opts *ParseOptions)
7373
return ast, err
7474
}
7575

76-
// Manifest returns a driver manifest.
77-
func (d *driverImpl) Manifest() (manifest.Manifest, error) {
78-
return *d.m, nil // TODO: clone
76+
// Version returns driver version.
77+
func (d *driverImpl) Version(ctx context.Context) (Version, error) {
78+
return Version{
79+
Version: d.m.Version,
80+
Build: d.m.Build,
81+
}, nil
82+
}
83+
84+
// Languages returns a single driver manifest for the language supported by the driver.
85+
func (d *driverImpl) Languages(ctx context.Context) ([]manifest.Manifest, error) {
86+
return []manifest.Manifest{*d.m}, nil // TODO: clone
7987
}

driver/manifest/manifest.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,8 +95,9 @@ type Documentation struct {
9595
type Manifest struct {
9696
Name string `toml:"name"` // human-readable name
9797
Language string `toml:"language"`
98+
Aliases []string `toml:"aliases"` // language name aliases, see Enry/Linguist
9899
Version string `toml:"version,omitempty" json:",omitempty"`
99-
Build *time.Time `toml:"build,omitempty" json:",omitempty"`
100+
Build time.Time `toml:"build,omitempty" json:",omitempty"`
100101
Status DevelopmentStatus `toml:"status"`
101102
SDKVersion string `toml:"-"` // read from go.mod
102103
Documentation *Documentation `toml:"documentation,omitempty" json:",omitempty"`

driver/manifest/manifest_test.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import (
1212
var fixture = `
1313
name = "Foo"
1414
language = "foo"
15+
build = 0001-01-01T00:00:00Z
1516
status = ""
1617
features = ["ast", "uast", "roles"]
1718

driver/server/common.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ var DefaultDriver driver.Native = native.NewDriver("")
1111
var (
1212
// ManifestLocation location of the manifest file. Should not override
1313
// this variable unless you know what are you doing.
14-
ManifestLocation = "/opt/driver/etc/" + manifest.Filename
14+
ManifestLocation = driver.ManifestLocation
1515
)
1616

1717
// Run is a common main function used as an entry point for drivers.

driver/server/grpc.go

Lines changed: 47 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,32 +58,56 @@ func newDriverManifest(manifest *manifest.Manifest) protocol1.DriverManifest {
5858
}
5959
}
6060

61+
func containsLang(lang string, list []manifest.Manifest) bool {
62+
for _, m := range list {
63+
if m.Language == lang {
64+
return true
65+
}
66+
for _, l := range m.Aliases {
67+
if l == lang {
68+
return true
69+
}
70+
}
71+
}
72+
return false
73+
}
74+
75+
// SupportedLanguages implements protocol1.Service.
6176
func (s service) SupportedLanguages(_ *protocol1.SupportedLanguagesRequest) *protocol1.SupportedLanguagesResponse {
62-
m, _ := s.d.Manifest()
63-
return &protocol1.SupportedLanguagesResponse{Languages: []protocol1.DriverManifest{
64-
newDriverManifest(&m),
65-
}}
77+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
78+
defer cancel()
79+
list, err := s.d.Languages(ctx)
80+
if err != nil {
81+
return &protocol1.SupportedLanguagesResponse{Response: errResp(err)}
82+
}
83+
resp := &protocol1.SupportedLanguagesResponse{
84+
Response: protocol1.Response{Status: protocol1.Ok},
85+
}
86+
for _, m := range list {
87+
resp.Languages = append(resp.Languages, newDriverManifest(&m))
88+
}
89+
return resp
6690
}
6791

6892
func (s service) parse(mode driver.Mode, req *protocol1.ParseRequest) (nodes.Node, protocol1.Response) {
6993
start := time.Now()
70-
m, err := s.d.Manifest()
94+
ctx := context.Background()
95+
if req.Timeout > 0 {
96+
var cancel func()
97+
ctx, cancel = context.WithTimeout(ctx, req.Timeout)
98+
defer cancel()
99+
}
100+
list, err := s.d.Languages(ctx)
71101
if err != nil {
72102
r := errResp(err)
73103
r.Elapsed = time.Since(start)
74104
return nil, r
75105
}
76-
if req.Language != m.Language {
106+
if !containsLang(req.Language, list) {
77107
r := errResp(ErrUnsupportedLanguage.New(req.Language))
78108
r.Elapsed = time.Since(start)
79109
return nil, r
80110
}
81-
ctx := context.Background()
82-
if req.Timeout > 0 {
83-
var cancel func()
84-
ctx, cancel = context.WithTimeout(ctx, req.Timeout)
85-
defer cancel()
86-
}
87111
ast, err := s.d.Parse(ctx, req.Content, &driver.ParseOptions{
88112
Mode: mode,
89113
Language: req.Language,
@@ -100,6 +124,7 @@ func (s service) parse(mode driver.Mode, req *protocol1.ParseRequest) (nodes.Nod
100124
return ast, r
101125
}
102126

127+
// Parse implements protocol1.Service.
103128
func (s service) Parse(req *protocol1.ParseRequest) *protocol1.ParseResponse {
104129
ast, resp := s.parse(driver.ModeAnnotated, req)
105130
if resp.Status != protocol1.Ok {
@@ -119,6 +144,7 @@ func (s service) Parse(req *protocol1.ParseRequest) *protocol1.ParseResponse {
119144
}
120145
}
121146

147+
// NativeParse implements protocol1.Service.
122148
func (s service) NativeParse(req *protocol1.NativeParseRequest) *protocol1.NativeParseResponse {
123149
ast, resp := s.parse(driver.ModeNative, (*protocol1.ParseRequest)(req))
124150
if resp.Status != protocol1.Ok {
@@ -137,14 +163,17 @@ func (s service) NativeParse(req *protocol1.NativeParseRequest) *protocol1.Nativ
137163
}
138164
}
139165

166+
// Version implements protocol1.Service.
140167
func (s service) Version(req *protocol1.VersionRequest) *protocol1.VersionResponse {
141-
m, _ := s.d.Manifest()
168+
ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
169+
defer cancel()
142170

143-
r := &protocol1.VersionResponse{
144-
Version: m.Version,
171+
m, err := s.d.Version(ctx)
172+
if err != nil {
173+
return &protocol1.VersionResponse{Response: errResp(err)}
145174
}
146-
if m.Build != nil {
147-
r.Build = *m.Build
175+
return &protocol1.VersionResponse{
176+
Version: m.Version,
177+
Build: m.Build,
148178
}
149-
return r
150179
}

driver/server/server.go

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
package server
22

33
import (
4+
"context"
45
"flag"
6+
"fmt"
57
"io"
68
"net"
79
"os"
@@ -81,10 +83,13 @@ func (s *Server) initialize() error {
8183
if err := s.initializeLogger(); err != nil {
8284
return err
8385
}
84-
m, err := s.d.Manifest()
86+
list, err := s.d.Languages(context.Background())
8587
if err != nil {
8688
return err
89+
} else if len(list) != 1 {
90+
return fmt.Errorf("expected exactly one manifest, got %d", len(list))
8791
}
92+
m := list[0]
8893
if err := s.initializeTracing(m.Language + "-driver"); err != nil {
8994
return err
9095
}
@@ -96,7 +101,7 @@ func (s *Server) initialize() error {
96101
}
97102

98103
build := "unknown"
99-
if m.Build != nil {
104+
if !m.Build.IsZero() {
100105
build = m.Build.Format("2006-01-02T15:04:05Z")
101106
}
102107
s.Logger.Infof("%s-driver version: %s (build: %s)",

0 commit comments

Comments
 (0)