From 0d285a85dca6abe27e43f860c184130eaba76dd9 Mon Sep 17 00:00:00 2001 From: Rijnard van Tonder Date: Fri, 29 Apr 2022 12:07:52 -0700 Subject: [PATCH] compute: don't hydrate file contents for "type:path" (#34681) --- enterprise/internal/compute/output_command.go | 9 +++++++-- enterprise/internal/compute/output_command_test.go | 5 +++++ enterprise/internal/compute/query.go | 13 ++++++++++++- 3 files changed, 24 insertions(+), 3 deletions(-) diff --git a/enterprise/internal/compute/output_command.go b/enterprise/internal/compute/output_command.go index e371166a367..b8480a10aeb 100644 --- a/enterprise/internal/compute/output_command.go +++ b/enterprise/internal/compute/output_command.go @@ -19,6 +19,7 @@ type Output struct { OutputPattern string Separator string Selector string + TypeValue string } func (c *Output) ToSearchPattern() string { @@ -61,11 +62,14 @@ func output(ctx context.Context, fragment string, matchPattern MatchPattern, rep return &Text{Value: newContent, Kind: "output"}, nil } -func resultContent(ctx context.Context, db database.DB, r result.Match) (string, bool, error) { +func resultContent(ctx context.Context, db database.DB, r result.Match, onlyPath bool) (string, bool, error) { switch m := r.(type) { case *result.RepoMatch: return string(m.Name), true, nil case *result.FileMatch: + if onlyPath { + return m.Path, true, nil + } contentBytes, err := git.ReadFile(ctx, db, m.Repo.Name, m.CommitID, m.Path, authz.DefaultSubRepoPermsChecker) if err != nil { return "", false, err @@ -85,7 +89,8 @@ func resultContent(ctx context.Context, db database.DB, r result.Match) (string, } func (c *Output) Run(ctx context.Context, db database.DB, r result.Match) (Result, error) { - content, ok, err := resultContent(ctx, db, r) + onlyPath := c.TypeValue == "path" // don't read file contents for file matches when we only want type:path + content, ok, err := resultContent(ctx, db, r, onlyPath) if err != nil { return nil, err } diff --git a/enterprise/internal/compute/output_command_test.go b/enterprise/internal/compute/output_command_test.go index a924d345a4f..330cd22198e 100644 --- a/enterprise/internal/compute/output_command_test.go +++ b/enterprise/internal/compute/output_command_test.go @@ -93,6 +93,11 @@ func TestRun(t *testing.T) { "my/awesome/repo"). Equal(t, test(`lang:ocaml content:output((\d) -> $repo) select:repo`, fileMatch("a 1 b 2 c 3"))) + autogold.Want( + "honor type:path efficiently (don't hydrate file content when type:path is set)", + "my/awesome/path.ml content is my/awesome/path.ml with extension: ml\n"). + Equal(t, test(`content:output(awesome/.+\.(\w+) -> $path content is $content with extension: $1) type:path`, fileMatch("a 1 b 2 c 3"))) + autogold.Want( "template substitution regexp with commit author", "bob: (1)\nbob: (2)\nbob: (3)\n"). diff --git a/enterprise/internal/compute/query.go b/enterprise/internal/compute/query.go index 9dafc2c0d3d..e981ee5e634 100644 --- a/enterprise/internal/compute/query.go +++ b/enterprise/internal/compute/query.go @@ -194,13 +194,24 @@ func parseOutput(q *query.Basic) (Command, bool, error) { return nil, false, nil } + var typeValue string + query.VisitField(q.ToParseTree(), query.FieldType, func(value string, _ bool, _ query.Annotation) { + typeValue = value + }) + var selector string query.VisitField(q.ToParseTree(), query.FieldSelect, func(value string, _ bool, _ query.Annotation) { selector = value }) // The default separator is newline and cannot be changed currently. - return &Output{SearchPattern: matchPattern, OutputPattern: right, Separator: "\n", Selector: selector}, true, nil + return &Output{ + SearchPattern: matchPattern, + OutputPattern: right, + Separator: "\n", + TypeValue: typeValue, + Selector: selector, + }, true, nil } func parseMatchOnly(q *query.Basic) (Command, bool, error) {