-
Notifications
You must be signed in to change notification settings - Fork 46
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
✨ Add preliminary python support #348
Conversation
Signed-off-by: JonahSussman <[email protected]>
Signed-off-by: JonahSussman <[email protected]>
Signed-off-by: JonahSussman <[email protected]>
Signed-off-by: Jonah Sussman <[email protected]>
Signed-off-by: JonahSussman <[email protected]>
Signed-off-by: JonahSussman <[email protected]>
Signed-off-by: JonahSussman <[email protected]>
- name: run demo image and ensure violations output unchanged | ||
run: | | ||
podman run -v $(pwd)/demo-output.yaml:/analyzer-lsp/output.yaml:Z localhost/testing:latest | ||
git diff --exit-code demo-output.yaml | ||
diff \ | ||
<(sort <(sed 's/incidents\.[0-9]\+/incidents\.x/g' <(yq -P 'sort_keys(..)' -o=props <(git show HEAD:demo-output.yaml)))) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what sorcery is this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since the incidents in a violation can be returned in any order, git diff
kept failing. i.e. git diff
would compare
sample-rule:
incidents:
- A
- B
sample-rule:
incidents:
- B
- A
and fail. This is because diff only compares the textual differences between the files. It has no knowledge of the YAML structure. To fix this, I installed yq
which allows us to examine the actual structure of the input YAML. My whole goal was to still use diff
to compare the two files, but make the position of each incident in the array irrelevant.
Moving from right to left, I first get the different versions of demo-output.yaml
. I then pipe that into yq
, with the -o=props
flag . -P 'sort_keys(..)'
is actually unnecessary due to what I do later. If we piped the YAML files I showed into that, it would return:
sample-rule.incidents.0 = A
sample-rule.incidents.1 = B
sample-rule.incidents.0 = B
sample-rule.incidents.1 = A
I then pipe that output into sed
, replacing every incidents.<number>
with incidents.x
to erase which index each element is in. Finally, I sort the result and diff
the two streams. Both files would return
sample-rule.incidents.x = A
sample-rule.incidents.x = B
Which is the same thing. No error, ta-da!
There might be a better way than cobbling together some shell commands for this. I wouldn't even be surprised if there was a way you could do all of this in yq
! At least one of the advantages of having it installed is that we can investigate the actual structure of the YAML now in our tests.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@JonahSussman lovely, I think this is a much better version of what we are doing in Kantra now, would love to copy it there
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would consider it a great honor, copy away! I would remove the -P 'sort_keys(..)'
part as I'm almost positive it's redundant.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we sort these in the engine then?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks good, a few comments but I don't believe any of them are blockers.
I am curious though, after looking into our fallback symbol searching, if we could accept some func
s for the handling of some of the differences between different language servers. That may enable us to make the generic provider work down to the lowest common denominator and have specific examples for golang/pythong/typescript/etc on how to extend it to handle peculiarities between the different implementations.
client := generic.NewGenericProvider() | ||
|
||
golangSC, err := client.Init(ctx, log, provider.InitConfig{ | ||
Location: "/home/jonah/Projects/analyzer-lsp/examples/golang", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This path doesn't look like one we'd want to commit.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, Eiher we remove this, or we make this more generic for testing.
I would think that removing for this PR and then coming back and making it easy to test w/ the generic provider makes sense to me. OR we make this a feature of kantra, and work on it from that the layer?
IDK just don't know if we want to change this particular main file yet but I could be wrong
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Whoops, will fix! Is leaving in the mainDebug()
function a problem as well? I just found all the stuff I put in there extremely useful when I was having problems.
func (p *genericServiceClient) GetAllSymbols(ctx context.Context, query string) []protocol.WorkspaceSymbol { | ||
// Returns all symbols for the given query. | ||
// NOTE: Only returns definitions when server does not supoprt workspace/symbol. | ||
// Is is intended behavior? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the .NET work, what made the most sense while experimenting was to:
- find occurrences of pattern
- call "textDocument/definition" and see if the response URI includes the referenced namespace (ie. System.Web.Mvc)...if it does then we add it as an incident.
And, iirc @fabianvf had mentioned gopls handling references
differently which would mean that this is yet another area where differences in implementation may bite us. Makes me wonder if we want to make it possible to pass a callback
of sorts that allows you to specify a function for determining if a found Symbol using the fallback method should be included as an incident.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If I'm understanding right, you're saying the .NET work utilizes the fallback method? I added the note as if we use the fallback method, only the definitions will be returned, rather than every symbol like when using workspace/symbol
. Honestly, I'm not quite seeing why we should do anything other than the fallback method?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I copy/pasted and then modified the fallback method for what I was doing with the .NET work. See here.
My thought was that it may be possible for us to create an exported method for our fallback that accepts a func
for determining if a given symbol is the one the provider is looking for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looking more thoroughly at what I did, it may be best for us to have our fallback method as an exported function that simply returns a slice of positions...leaving it up to the caller on how to sort which of those positions are valid symbols or not.
@@ -0,0 +1,151 @@ | |||
package protocol |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am hopeful that we can move to https://github.com/go-language-server/protocol but I think that's an important-long-term
type issue. Do we agree? I can writeup the issue later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Definitely something I want to investigate. Any way we can make it less brittle is a win in my book
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
More of slight clean ups and follow up issues that need to be created.
I do want to understand why we are exposing the ServiceClient. I thought that the interface should fully cover what anything else needed to do with it.
- name: run demo image and ensure violations output unchanged | ||
run: | | ||
podman run -v $(pwd)/demo-output.yaml:/analyzer-lsp/output.yaml:Z localhost/testing:latest | ||
git diff --exit-code demo-output.yaml | ||
diff \ | ||
<(sort <(sed 's/incidents\.[0-9]\+/incidents\.x/g' <(yq -P 'sort_keys(..)' -o=props <(git show HEAD:demo-output.yaml)))) \ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we sort these in the engine then?
@@ -21,6 +21,9 @@ FROM jaegertracing/all-in-one:latest AS jaeger-builder | |||
# The unofficial base image w/ jdtls and gopls installed | |||
FROM quay.io/konveyor/jdtls-server-base | |||
|
|||
RUN python3 -m ensurepip --upgrade |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Note to selves, we need to eventually find a way to have these broken up and use some shared filesystem while running. Probably something for Kantra to figure out. Do we have an issue for this?
client := generic.NewGenericProvider() | ||
|
||
golangSC, err := client.Init(ctx, log, provider.InitConfig{ | ||
Location: "/home/jonah/Projects/analyzer-lsp/examples/golang", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMO, Eiher we remove this, or we make this more generic for testing.
I would think that removing for this PR and then coming back and making it easy to test w/ the generic provider makes sense to me. OR we make this a feature of kantra, and work on it from that the layer?
IDK just don't know if we want to change this particular main file yet but I could be wrong
rpc *jsonrpc2.Conn | ||
cancelFunc context.CancelFunc | ||
cmd *exec.Cmd | ||
type GenericServiceClient struct { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why exporting the service client?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Had it for debugging stuff, changing it back
|
||
// 2-tiered table for each language and their respective fixes we may need to | ||
// apply | ||
var SubstitutionTable = map[string]map[string]string{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you add to the documentation for the specific python one why we need to substitute what? I can see the diff but am confused about the why.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Will add to the python-provider.md
doc!
provider/internal/grpc/README.md
Outdated
@@ -1,5 +1,17 @@ | |||
To update the Provider GRPC definition, update `library.proto` and run: | |||
To install protoc, go to https://github.com/protocolbuffers/protobuf/releases |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This will only work for Linux, I would recommend that we point to the install docs for protoc instead.
provider/provider.go
Outdated
@@ -102,12 +102,25 @@ const ( | |||
type InitConfig struct { | |||
// This is the location of the code base that the | |||
// Provider will be responisble for parsing | |||
// Deprecated: rootUri, which is what this maps to in the LSP spec, is deprecated. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can you create issues in the repo for this and link in the deprecated or a TODO?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! #365
@djzager I really want to investigate a good way to do this. The vast majority of the functionality between different providers seems the same. Would love to have a discussion about what that looks like |
…"Run" go-routine Signed-off-by: JonahSussman <[email protected]>
Signed-off-by: JonahSussman <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit's but the core is good
cancelFunc: cancelFunc, | ||
cmd: cmd, | ||
config: c, | ||
Rpc: rpc, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
nit: If changing, then it should be RPC
config: c, | ||
Rpc: rpc, | ||
CancelFunc: cancelFunc, | ||
Cmd: cmd, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
CMD
as well
jsonrpc2/jsonrpc2.go
Outdated
@@ -127,6 +139,9 @@ func (c *Conn) Call(ctx context.Context, method string, params, result interface | |||
h.Done(ctx, err) | |||
} | |||
}() | |||
|
|||
// fmt.Printf("Sending: %s\n", string(data)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
lets remove this instead of commenting IMO
Signed-off-by: JonahSussman <[email protected]>
Big PR, hopefully I didn't break anything