Skip to content

Commit 3664533

Browse files
authored
function: implement is_vendor function (#830)
function: implement is_vendor function
2 parents 63a9035 + 9493b55 commit 3664533

File tree

4 files changed

+115
-0
lines changed

4 files changed

+115
-0
lines changed

integration_test.go

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,15 @@ func TestIntegration(t *testing.T) {
345345
`,
346346
[]sql.Row{{"worktree", int64(9)}},
347347
},
348+
{
349+
`SELECT cf.file_path
350+
FROM refs r
351+
INNER JOIN commit_files cf
352+
ON r.commit_hash = cf.commit_hash
353+
AND r.repository_id = cf.repository_id
354+
WHERE r.ref_name = 'HEAD' AND IS_VENDOR(cf.file_path)`,
355+
[]sql.Row{{".gitignore"}, {"vendor/foo.go"}},
356+
},
348357
}
349358

350359
var pid uint64

internal/function/is_vendor.go

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
package function
2+
3+
import (
4+
"fmt"
5+
6+
enry "gopkg.in/src-d/enry.v1"
7+
"gopkg.in/src-d/go-mysql-server.v0/sql"
8+
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
9+
)
10+
11+
// IsVendor reports whether files are vendored or not.
12+
type IsVendor struct {
13+
expression.UnaryExpression
14+
}
15+
16+
// NewIsVendor creates a new IsVendor function.
17+
func NewIsVendor(filePath sql.Expression) sql.Expression {
18+
return &IsVendor{expression.UnaryExpression{Child: filePath}}
19+
}
20+
21+
// Type implements the sql.Expression interface.
22+
func (v *IsVendor) Type() sql.Type { return sql.Boolean }
23+
24+
// Eval implements the sql.Expression interface.
25+
func (v *IsVendor) Eval(ctx *sql.Context, row sql.Row) (interface{}, error) {
26+
span, ctx := ctx.Span("function.IsVendor")
27+
defer span.Finish()
28+
29+
val, err := v.Child.Eval(ctx, row)
30+
if err != nil {
31+
return nil, err
32+
}
33+
34+
if val == nil {
35+
return nil, nil
36+
}
37+
38+
val, err = sql.Text.Convert(val)
39+
if err != nil {
40+
return nil, err
41+
}
42+
43+
return enry.IsVendor(val.(string)), nil
44+
}
45+
46+
func (v *IsVendor) String() string {
47+
return fmt.Sprintf("IS_VENDOR(%s)", v.Child)
48+
}
49+
50+
// TransformUp implements the sql.Expression interface.
51+
func (v *IsVendor) TransformUp(f sql.TransformExprFunc) (sql.Expression, error) {
52+
child, err := v.Child.TransformUp(f)
53+
if err != nil {
54+
return nil, err
55+
}
56+
57+
return f(NewIsVendor(child))
58+
}

internal/function/is_vendor_test.go

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
package function
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
"gopkg.in/src-d/go-mysql-server.v0/sql"
8+
"gopkg.in/src-d/go-mysql-server.v0/sql/expression"
9+
)
10+
11+
func TestIsVendor(t *testing.T) {
12+
testCases := []struct {
13+
name string
14+
path interface{}
15+
expected interface{}
16+
}{
17+
{
18+
"non vendored path",
19+
"some/folder/foo.go",
20+
false,
21+
},
22+
{
23+
"nil",
24+
nil,
25+
nil,
26+
},
27+
{
28+
"vendored path",
29+
"vendor/foo.go",
30+
true,
31+
},
32+
{
33+
"vendored (no root) path",
34+
"foo/bar/vendor/foo.go",
35+
true,
36+
},
37+
}
38+
39+
fn := NewIsVendor(expression.NewGetField(0, sql.Text, "x", true))
40+
for _, tt := range testCases {
41+
t.Run(tt.name, func(t *testing.T) {
42+
result, err := fn.Eval(sql.NewEmptyContext(), sql.Row{tt.path})
43+
require.NoError(t, err)
44+
require.Equal(t, tt.expected, result)
45+
})
46+
}
47+
}

internal/function/registry.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,4 +13,5 @@ var Functions = []sql.Function{
1313
sql.Function2{Name: "uast_xpath", Fn: NewUASTXPath},
1414
sql.Function2{Name: "uast_extract", Fn: NewUASTExtract},
1515
sql.Function1{Name: "uast_children", Fn: NewUASTChildren},
16+
sql.Function1{Name: "is_vendor", Fn: NewIsVendor},
1617
}

0 commit comments

Comments
 (0)