Skip to content

Commit

Permalink
Support label using regexp in directive gazelle:resolve_regexp (#1822)
Browse files Browse the repository at this point in the history
* Add ability to resolve label using regexp in directive resolve_regexp

* Add unit tests and update documentation

Fix formatting

Update test

Format test

remove extra whitespace

Trigger tests

Fix space
  • Loading branch information
lkassar-stripe authored Aug 1, 2024
1 parent 50f6959 commit 226b5ab
Show file tree
Hide file tree
Showing 3 changed files with 42 additions and 3 deletions.
5 changes: 4 additions & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -1008,14 +1008,17 @@ The following directives are recognized:
| ``import-lang`` may be omitted if it is the same as ``source-lang``. |
| * ``import-string-regex`` is the regex applied to the import in the source code. |
| If it matches, that import will be resolved to the label specified below. |
| * ``label`` is the Bazel label that Gazelle should write in ``deps``. |
| * ``label`` is the Bazel label that Gazelle should write in ``deps``. The label |
| can be constructed using captured strings from the subpattern matching in |
| import-string-regex |
| |
| For example: |
| |
| .. code:: bzl |
| |
| # gazelle:resolve_regexp go example.com/.* //foo:go_default_library |
| # gazelle:resolve_regexp proto go foo/.*\.proto //foo:foo_go_proto |
| # gazelle:resolve_regexp proto go foo/(.*)\.proto //foo/$1:foo_rule_proto |
| |
+---------------------------------------------------+----------------------------------------+
| :direc:`# gazelle:go_visibility label` | n/a |
Expand Down
14 changes: 13 additions & 1 deletion resolve/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ func FindRuleWithOverride(c *config.Config, imp ImportSpec, lang string) (label.
for i := len(rc.regexpOverrides) - 1; i >= 0; i-- {
o := rc.regexpOverrides[i]
if o.matches(imp, lang) {
return o.dep, true
dep := o.resolveRegexpDep(imp)
return dep, true
}
}
return label.NoLabel, false
Expand All @@ -62,6 +63,17 @@ func (o regexpOverrideSpec) matches(imp ImportSpec, lang string) bool {
(o.lang == "" || o.lang == lang)
}

func (o regexpOverrideSpec) resolveRegexpDep(imp ImportSpec) label.Label {

resolvedDepWithRegex := o.ImpRegex.ReplaceAllString(imp.Imp, o.dep.String())
resolvedLabel, err := label.Parse(resolvedDepWithRegex)
if err != nil {
return o.dep
}

return resolvedLabel
}

type resolveConfig struct {
overrides map[overrideKey]label.Label
regexpOverrides []regexpOverrideSpec
Expand Down
26 changes: 25 additions & 1 deletion resolve/resolve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ package resolve
import (
"testing"

"github.com/bazelbuild/bazel-gazelle/rule"
"github.com/bazelbuild/bazel-gazelle/config"
"github.com/bazelbuild/bazel-gazelle/label"
"github.com/bazelbuild/bazel-gazelle/rule"
"github.com/google/go-cmp/cmp"
)

Expand All @@ -22,6 +22,14 @@ func TestFindRuleWithOverride_ParentTraversal(t *testing.T) {

secondChildCfg := getConfig(t, "second/child/rel", nil, rootCfg)

dualResolveRegexpCfg := getConfig(t, "dual/resolve/regexp", []rule.Directive{
{Key: "resolve_regexp", Value: "go ^github.com/foo/(.*)$ @com_example//$1:replacement"},
}, rootCfg)

multipleExpDualResolveRegexpCfg := getConfig(t, "multi/dual/resolve/regexp", []rule.Directive{
{Key: "resolve_regexp", Value: "go ^github.com/foo/(.*)/(.*)$ @com_example//$1/bar_sub_dir/$2:replacement"},
}, rootCfg)

tests := []struct {
name string
cfg *config.Config
Expand Down Expand Up @@ -86,6 +94,22 @@ func TestFindRuleWithOverride_ParentTraversal(t *testing.T) {
want: getTestLabel(t, "@com_example//root:replacement"),
wantFound: true,
},
{
name: "Target resolves to label populated by regexp",
cfg: dualResolveRegexpCfg,
importSpec: ImportSpec{Lang: "go", Imp: "github.com/foo/foo_package"},
lang: "go",
want: getTestLabel(t, "@com_example//foo_package:replacement"),
wantFound: true,
},
{
name: "Target resolves to label populated by multipe captured regexp",
cfg: multipleExpDualResolveRegexpCfg,
importSpec: ImportSpec{Lang: "go", Imp: "github.com/foo/foo_package/baz"},
lang: "go",
want: getTestLabel(t, "@com_example//foo_package/bar_sub_dir/baz:replacement"),
wantFound: true,
},
}

for _, tt := range tests {
Expand Down

0 comments on commit 226b5ab

Please sign in to comment.