Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add warning for calls to provider without doc or fields. #879

Merged
merged 4 commits into from
Jul 24, 2020
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions WARNINGS.md
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Warning categories supported by buildifier's linter:
* [`package-on-top`](#package-on-top)
* [`positional-args`](#positional-args)
* [`print`](#print)
* [`provider-params`](#provider-params)
* [`redefined-variable`](#redefined-variable)
* [`repository-name`](#repository-name)
* [`return-value`](#return-value)
Expand Down Expand Up @@ -796,6 +797,38 @@ may never see the warning.

--------------------------------------------------------------------------------

## <a name="provider-params"></a>Calls to 'provider' should specify a list of fields and a documentation

* Category name: `provider-params`
* Automatic fix: no

Calls to `provider` should specify a documentation string and a list of fields:

```python
fooInfo = provider(
laurentlb marked this conversation as resolved.
Show resolved Hide resolved
doc = "Some documentation.",
fields = ["field1", "field2"],
)
```

Fields should also be documented when needed:

```python
provider(
doc = "Some documentation.",
fields = {
"field1": "Documentation for field1",
"field2': "Documentation for field2",
})
``

Note that specifying a list of fields is a breaking change. It is an error if a
laurentlb marked this conversation as resolved.
Show resolved Hide resolved
call to the provider uses undeclared fields.

See the [documentation for providers](https://docs.bazel.build/versions/master/skylark/lib/globals.html#provider).

--------------------------------------------------------------------------------

## <a name="redefined-variable"></a>Variable has already been defined

* Category name: `redefined-variable`
Expand Down
1 change: 1 addition & 0 deletions warn/warn.go
Original file line number Diff line number Diff line change
Expand Up @@ -144,6 +144,7 @@ var FileWarningMap = map[string]func(f *build.File) []*LinterFinding{
"package-name": packageNameWarning,
"package-on-top": packageOnTopWarning,
"print": printWarning,
"provider-params": providerParamsWarning,
"redefined-variable": redefinedVariableWarning,
"repository-name": repositoryNameWarning,
"rule-impl-return": ruleImplReturnWarning,
Expand Down
30 changes: 30 additions & 0 deletions warn/warn_bazel_api.go
Original file line number Diff line number Diff line change
Expand Up @@ -1008,3 +1008,33 @@ func keywordPositionalParametersWarning(f *build.File) []*LinterFinding {

return findings
}

func providerParamsWarning(f *build.File) []*LinterFinding {
if f.Type != build.TypeBzl {
return nil
}

var findings []*LinterFinding
build.Walk(f, func(expr build.Expr, stack []build.Expr) {
call, ok := isFunctionCall(expr, "provider")
if !ok {
return
}

_, _, fields := getParam(call.List, "fields")
_, _, doc := getParam(call.List, "doc")
// doc can also be the first positional argument
hasPositional := false
if len(call.List) > 0 {
if _, ok := call.List[0].(*build.AssignExpr); !ok {
hasPositional = true
}
}
if fields == nil || (doc == nil && !hasPositional) {
laurentlb marked this conversation as resolved.
Show resolved Hide resolved
findings = append(findings, makeLinterFinding(call,
laurentlb marked this conversation as resolved.
Show resolved Hide resolved
`Calls to 'provider' should specify a list of fields and a documentation:\n`+
` provider("description", fields = [...])`))
}
})
return findings
}
13 changes: 12 additions & 1 deletion warn/warn_bazel_api_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@ package warn

import (
"fmt"
"github.com/bazelbuild/buildtools/tables"
"testing"

"github.com/bazelbuild/buildtools/tables"
)

func TestAttrConfigurationWarning(t *testing.T) {
Expand Down Expand Up @@ -749,3 +750,13 @@ getattr(
`:12: Keyword parameter "default" for "getattr" should be positional.`,
}, scopeEverywhere)
}

func TestProvider(t *testing.T) {
checkFindings(t, "provider-params", `provider(doc = "doc", fields = [])`, []string{}, scopeBzl)
checkFindings(t, "provider-params", `provider("doc", fields = [])`, []string{}, scopeBzl)

err := `1: Calls to 'provider' should specify a list of fields and a documentation:\n provider("description", fields = [...])`
checkFindings(t, "provider-params", `provider(fields = [])`, []string{err}, scopeBzl)
checkFindings(t, "provider-params", `provider(doc = "doc")`, []string{err}, scopeBzl)
checkFindings(t, "provider-params", `p = provider()`, []string{err}, scopeBzl)
}