github.com/grafana/pyroscope@v1.18.0/pkg/frontend/vcs/source/find_java.go (about)

     1  package source
     2  
     3  import (
     4  	"context"
     5  	"errors"
     6  	"strings"
     7  
     8  	"connectrpc.com/connect"
     9  	"github.com/go-kit/log/level"
    10  	"github.com/opentracing/opentracing-go"
    11  
    12  	vcsv1 "github.com/grafana/pyroscope/api/gen/proto/go/vcs/v1"
    13  	"github.com/grafana/pyroscope/pkg/frontend/vcs/client"
    14  	"github.com/grafana/pyroscope/pkg/frontend/vcs/config"
    15  )
    16  
    17  const (
    18  	ExtJava = ".java"
    19  )
    20  
    21  func convertJavaFunctionNameToPath(functionName string) string {
    22  	pathSegments := strings.Split(functionName, "/")
    23  	last := len(pathSegments) - 1
    24  
    25  	// pos to cut from
    26  	pos := -1
    27  	updatePos := func(v int) {
    28  		if v == -1 {
    29  			return
    30  		}
    31  		if pos == -1 || pos > v {
    32  			pos = v
    33  		}
    34  	}
    35  
    36  	// find first dot in last segment
    37  	updatePos(strings.Index(pathSegments[last], "."))
    38  
    39  	// find first $ in last segment
    40  	updatePos(strings.Index(pathSegments[last], "$"))
    41  
    42  	if pos > 0 {
    43  		pathSegments[last] = pathSegments[last][:pos]
    44  	}
    45  
    46  	pathSegments[last] = pathSegments[last] + ExtJava
    47  	return strings.Join(pathSegments, "/")
    48  }
    49  
    50  // findJavaFile finds a java file in a vcs repository.
    51  func (ff FileFinder) findJavaFile(ctx context.Context, mappings ...*config.MappingConfig) (*vcsv1.GetFileResponse, error) {
    52  	sp, ctx := opentracing.StartSpanFromContext(ctx, "findJavaFile")
    53  	defer sp.Finish()
    54  	sp.SetTag("file.function_name", ff.file.FunctionName)
    55  	sp.SetTag("file.path", ff.file.Path)
    56  
    57  	javaPath := convertJavaFunctionNameToPath(ff.file.FunctionName)
    58  	for _, m := range mappings {
    59  		resp, err := ff.fetchMappingFile(ctx, m, javaPath)
    60  		if err != nil {
    61  			if errors.Is(err, client.ErrNotFound) {
    62  				continue
    63  			}
    64  			level.Warn(ff.logger).Log("msg", "failed to fetch mapping file", "err", err)
    65  			continue
    66  		}
    67  		return resp, nil
    68  	}
    69  
    70  	return nil, connect.NewError(connect.CodeNotFound, errors.New("no mappings provided, file not resolvable"))
    71  }