Skip to content

Commit

Permalink
✨ Path inclusion (konveyor#606)
Browse files Browse the repository at this point in the history
Bundle PR: 94

---------

Signed-off-by: Pranav Gaikwad <pgaikwad@redhat.com>
  • Loading branch information
pranavgaikwad authored May 20, 2024
1 parent 8aa5f98 commit 8af6f5c
Show file tree
Hide file tree
Showing 20 changed files with 452 additions and 61 deletions.
40 changes: 32 additions & 8 deletions .github/workflows/demo-testing.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,25 +13,49 @@ jobs:
env:
PULL_REQUEST_BODY: ${{ github.event.pull_request.body }}
run: |
echo "BUILD_BUNDLE=false" >> $GITHUB_OUTPUT
# if this is a PR, we should use the base branch
# else, use the branch on which this is running
if [ ! -z ${GITHUB_BASE_REF} ]; then
echo "Using ${GITHUB_BASE_REF}"
echo "API_TESTS_REF=${GITHUB_BASE_REF}" >> $GITHUB_OUTPUT
echo "ADDON_REF=${GITHUB_BASE_REF}" >>$GITHUB_ENV
echo "ADDON_REF=${GITHUB_BASE_REF}" >>$GITHUB_OUTPUT
echo "JAVA_BUNDLE_REF=${GITHUB_BASE_REF}" >>$GITHUB_OUTPUT
else
echo "Using ${GITHUB_REF_NAME}"
echo "API_TESTS_REF=${GITHUB_REF_NAME}" >> $GITHUB_OUTPUT
echo "ADDON_REF=${GITHUB_REF_NAME}" >>$GITHUB_ENV
echo "ADDON_REF=${GITHUB_REF_NAME}" >>$GITHUB_OUTPUT
echo "JAVA_BUNDLE_REF=${GITHUB_REF_NAME}" >>$GITHUB_OUTPUT
fi
# override with explicitely set value in PR description
echo "${PULL_REQUEST_BODY}"
PULL_REQUEST_NUMBER=$(echo "${PULL_REQUEST_BODY}" | grep -oP '[A|a]ddon [P|p][R|r]: \K\d+' || true)
if [ ! -z "$PULL_REQUEST_NUMBER" ]; then
echo "Using pull/${PULL_REQUEST_NUMBER} for addon"
echo "ADDON_REF=refs/pull/$PULL_REQUEST_NUMBER/merge" >>$GITHUB_ENV
fi
ADDON_PULL_REQUEST_NUMBER=$(echo "${PULL_REQUEST_BODY}" | grep -oP '[A|a]ddon [P|p][R|r]: \K\d+' || true)
if [ ! -z "$ADDON_PULL_REQUEST_NUMBER" ]; then
echo "Using pull/${ADDON_PULL_REQUEST_NUMBER} for addon"
echo "ADDON_REF=refs/pull/$ADDON_PULL_REQUEST_NUMBER/merge" >>$GITHUB_OUTPUT
fi
JAVA_BUNDLE_PR_NUMBER=$(echo "${PULL_REQUEST_BODY}" | grep -oP '[B|b]undle [P|p][R|r]: \K\d+' || true)
if [ ! -z "$JAVA_BUNDLE_PR_NUMBER" ]; then
echo "Using bundle PR pull/${JAVA_BUNDLE_PR_NUMBER}"
echo "JAVA_BUNDLE_REF=refs/pull/$JAVA_BUNDLE_PR_NUMBER/merge" >> $GITHUB_OUTPUT
echo "BUILD_BUNDLE=true" >>$GITHUB_OUTPUT
fi
- uses: actions/checkout@v3
if: steps.extract-info.outputs.BUILD_BUNDLE
with:
fetch-depth: 0
repository: konveyor/java-analyzer-bundle
ref: "${{ steps.extract-info.outputs.JAVA_BUNDLE_REF }}"
path: java-analyzer-bundle

- name: build java analyzer bundle image
if: steps.extract-info.outputs.BUILD_BUNDLE
working-directory: java-analyzer-bundle
run: |
podman build -t quay.io/konveyor/jdtls-server-base:latest -f Dockerfile .
- uses: actions/checkout@v3

Expand Down Expand Up @@ -64,7 +88,7 @@ jobs:
with:
fetch-depth: 0
repository: konveyor/tackle2-addon-analyzer
ref: "${{ env.ADDON_REF}}"
ref: ${{ steps.extract-info.outputs.ADDON_REF }}
path: tackle2-addon-analyzer

- name: Build addon and save image
Expand Down
125 changes: 109 additions & 16 deletions demo-output.yaml

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions examples/builtin/inclusion_tests/dir-0/inclusion-test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"description": "Does your JSON search work?",
"name": "test-your-json-search",
"inclusionTestNode": "Test this node"
}
5 changes: 5 additions & 0 deletions examples/builtin/inclusion_tests/dir-0/inclusion-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<xmlTest>
<description>Does your XML search work?</description>
<name>xml-search</name>
<inclusionTestNode>Test this node</inclusionTestNode>
</xmlTest>
5 changes: 5 additions & 0 deletions examples/builtin/inclusion_tests/inclusion-test.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"description": "Does your JSON search work?",
"name": "test-your-json-search",
"inclusionTestNode": "Test this node"
}
5 changes: 5 additions & 0 deletions examples/builtin/inclusion_tests/inclusion-test.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<xmlTest>
<description>Does your XML search work?</description>
<name>xml-search</name>
<inclusionTestNode>Test this node</inclusionTestNode>
</xmlTest>
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package com.example.apps;

import java.io.File;
import io.fabric8.kubernetes.api.model.apiextensions.v1beta1.CustomResourceDefinition;

public class App
Expand All @@ -16,5 +17,11 @@ public static void main( String[] args )

GenericClass<String> element = new GenericClass<String>("Hello world!");
element.get();

// test file usage
File file = new File("test");
if (file.exists()) {
System.out.println("file exists");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@

@Singleton
public abstract class Bean implements SessionBean {

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
package com.example.apps.util;

import java.io.File;

public class FileReader {
public static void main(String[] args) {
File file = new File("test");
if (file.exists()) {
System.out.println("file exists");
}
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,7 @@ func (p *javaProvider) Init(ctx context.Context, log logr.Logger, config provide
isLocationBinary: isBinary,
mvnSettingsFile: mavenSettingsFile,
depsLocationCache: make(map[string]int),
includedPaths: provider.GetIncludedPathsFromConfig(config, false),
}

svcClient.initialization(ctx)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ type javaServiceClient struct {
depsMutex sync.RWMutex
depsCache map[uri.URI][]*provider.Dep
depsLocationCache map[string]int
includedPaths []string
}

type depLabelItem struct {
Expand Down Expand Up @@ -101,13 +102,18 @@ func (p *javaServiceClient) GetAllSymbols(ctx context.Context, query, location s
// This command will run the added bundle to the language server. The command over the wire needs too look like this.
// in this case the project is hardcoded in the init of the Langauge Server above
// workspace/executeCommand '{"command": "io.konveyor.tackle.ruleEntry", "arguments": {"query":"*customresourcedefinition","project": "java"}}'
argumentsMap := map[string]string{
argumentsMap := map[string]interface{}{
"query": query,
"project": "java",
"location": fmt.Sprintf("%v", locationToCode[strings.ToLower(location)]),
"analysisMode": string(p.config.AnalysisMode),
}

if p.includedPaths != nil && len(p.includedPaths) > 0 {
argumentsMap[provider.IncludedPathsConfigKey] = p.includedPaths
p.log.V(5).Info("setting search scope by filepaths", "paths", p.includedPaths)
}

argumentsBytes, _ := json.Marshal(argumentsMap)
arguments := []json.RawMessage{argumentsBytes}

Expand Down
1 change: 1 addition & 0 deletions provider/internal/builtin/provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -150,6 +150,7 @@ func (p *builtinProvider) Init(ctx context.Context, log logr.Logger, config prov
UnimplementedDependenciesComponent: provider.UnimplementedDependenciesComponent{},
locationCache: make(map[string]float64),
log: log,
includedPaths: provider.GetIncludedPathsFromConfig(config, true),
}, nil
}

Expand Down
105 changes: 72 additions & 33 deletions provider/internal/builtin/service_client.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ type builtinServiceClient struct {

cacheMutex sync.RWMutex
locationCache map[string]float64
includedPaths []string
}

type fileTemplateContext struct {
Expand Down Expand Up @@ -58,30 +59,24 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
return response, fmt.Errorf("unable to find files using pattern `%s`: %v", c.Pattern, err)
}

if len(matchingFiles) != 0 {
response.Matched = true
}

response.TemplateContext = map[string]interface{}{"filepaths": matchingFiles}
for _, match := range matchingFiles {
if filepath.IsAbs(match) {
response.Incidents = append(response.Incidents, provider.IncidentContext{
FileURI: uri.File(match),
})
continue

absPath := match
if !filepath.IsAbs(match) {
absPath, err = filepath.Abs(match)
if err != nil {
p.log.V(5).Error(err, "failed to get absolute path to file", "path", match)
absPath = match
}
}
ab, err := filepath.Abs(match)
if err != nil {
//TODO: Probably want to log or something to let us know we can't get absolute path here.
fmt.Printf("\n%v\n\n", err)
ab = match
if !p.isFileIncluded(absPath) {
continue
}
response.Incidents = append(response.Incidents, provider.IncidentContext{
FileURI: uri.File(ab),
FileURI: uri.File(absPath),
})

}
response.Matched = len(response.Incidents) > 0
return response, nil
case "filecontent":
c := cond.Filecontent
Expand Down Expand Up @@ -122,16 +117,21 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
continue
}

ab, err := filepath.Abs(pieces[0])
absPath, err := filepath.Abs(pieces[0])
if err != nil {
ab = pieces[0]
absPath = pieces[0]
}

if !p.isFileIncluded(absPath) {
continue
}

lineNumber, err := strconv.Atoi(pieces[1])
if err != nil {
return response, fmt.Errorf("cannot convert line number string to integer")
}
response.Incidents = append(response.Incidents, provider.IncidentContext{
FileURI: uri.File(ab),
FileURI: uri.File(absPath),
LineNumber: &lineNumber,
Variables: map[string]interface{}{
"matchingText": pieces[2],
Expand All @@ -155,7 +155,6 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
if err != nil {
return response, fmt.Errorf("unable to find XML files: %v", err)
}

for _, file := range xmlFiles {
nodes, err := queryXMLFile(file, query)
if err != nil {
Expand All @@ -165,12 +164,15 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
if len(nodes) != 0 {
response.Matched = true
for _, node := range nodes {
ab, err := filepath.Abs(file)
absPath, err := filepath.Abs(file)
if err != nil {
ab = file
absPath = file
}
if !p.isFileIncluded(absPath) {
continue
}
incident := provider.IncidentContext{
FileURI: uri.File(ab),
FileURI: uri.File(absPath),
Variables: map[string]interface{}{
"matchingXML": node.OutputXML(false),
"innerText": node.InnerText(),
Expand All @@ -181,7 +183,7 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
if content == "" {
content = node.Data
}
location, err := p.getLocation(ctx, ab, content)
location, err := p.getLocation(ctx, absPath, content)
if err == nil {
incident.CodeLocation = &location
lineNo := int(location.StartPosition.Line)
Expand All @@ -206,7 +208,6 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
if err != nil {
return response, fmt.Errorf("unable to find XML files: %v", err)
}

for _, file := range xmlFiles {
nodes, err := queryXMLFile(file, query)
if err != nil {
Expand All @@ -220,12 +221,15 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
if attr.Name.Local == "public-id" {
if regex.MatchString(attr.Value) {
response.Matched = true
ab, err := filepath.Abs(file)
absPath, err := filepath.Abs(file)
if err != nil {
ab = file
absPath = file
}
if !p.isFileIncluded(absPath) {
continue
}
response.Incidents = append(response.Incidents, provider.IncidentContext{
FileURI: uri.File(ab),
FileURI: uri.File(absPath),
Variables: map[string]interface{}{
"matchingXML": node.OutputXML(false),
"innerText": node.InnerText(),
Expand Down Expand Up @@ -268,18 +272,21 @@ func (p *builtinServiceClient) Evaluate(ctx context.Context, cap string, conditi
if len(list) != 0 {
response.Matched = true
for _, node := range list {
ab, err := filepath.Abs(file)
absPath, err := filepath.Abs(file)
if err != nil {
ab = file
absPath = file
}
if !p.isFileIncluded(absPath) {
continue
}
incident := provider.IncidentContext{
FileURI: uri.File(ab),
FileURI: uri.File(absPath),
Variables: map[string]interface{}{
"matchingJSON": node.InnerText(),
"data": node.Data,
},
}
location, err := p.getLocation(ctx, ab, node.InnerText())
location, err := p.getLocation(ctx, absPath, node.InnerText())
if err == nil {
incident.CodeLocation = &location
lineNo := int(location.StartPosition.Line)
Expand Down Expand Up @@ -451,3 +458,35 @@ func queryXMLFile(filePath string, query *xpath.Expr) (nodes []*xmlquery.Node, e
nodes = xmlquery.QuerySelectorAll(doc, query)
return nodes, err
}

// filterByIncludedPaths given a list of file paths,
// filters-out the ones not present in includedPaths
func (b *builtinServiceClient) isFileIncluded(absolutePath string) bool {
if b.includedPaths == nil || len(b.includedPaths) == 0 {
return true
}

getSegments := func(path string) []string {
segments := []string{}
path = filepath.Clean(path)
for _, segment := range strings.Split(
path, string(os.PathSeparator)) {
if segment != "" {
segments = append(segments, segment)
}
}
return segments
}

pathSegments := getSegments(absolutePath)
for _, includedPath := range b.includedPaths {
includedPathSegments := getSegments(includedPath)
if len(pathSegments) >= len(includedPathSegments) &&
strings.HasPrefix(strings.Join(pathSegments, ""),
strings.Join(includedPathSegments, "")) {
return true
}
}
b.log.V(5).Info("excluding file from search", "file", absolutePath)
return false
}
Loading

0 comments on commit 8af6f5c

Please sign in to comment.