Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Appearance settings

Commit 912a505

Browse filesBrowse files
authored
fix: make conftest.py special with gazelle (bazel-contrib#879)
* fix: add conftest.py to py_test generated targets Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * fix: use separate py_library for conftest.py This allows the conftest.py to be used on sub-directories as pytest would pick them up. Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * fix: add testonly to conftest py_library Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> * fix: testonly is a boolean, not a string Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com> Signed-off-by: Thulio Ferraz Assis <3149049+f0rmiga@users.noreply.github.com>
1 parent 3f0d62d commit 912a505
Copy full SHA for 912a505

File tree

Expand file treeCollapse file tree

11 files changed

+121
-12
lines changed
Filter options
Expand file treeCollapse file tree

11 files changed

+121
-12
lines changed

‎gazelle/generate.go

Copy file name to clipboardExpand all lines: gazelle/generate.go
+58-12Lines changed: 58 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,8 @@ const (
2626
pyBinaryEntrypointFilename = "__main__.py"
2727
pyTestEntrypointFilename = "__test__.py"
2828
pyTestEntrypointTargetname = "__test__"
29+
conftestFilename = "conftest.py"
30+
conftestTargetname = "conftest"
2931
)
3032

3133
var (
@@ -71,6 +73,7 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
7173
// be generated for this package or not.
7274
hasPyTestFile := false
7375
hasPyTestTarget := false
76+
hasConftestFile := false
7477

7578
for _, f := range args.RegularFiles {
7679
if cfg.IgnoresFile(filepath.Base(f)) {
@@ -81,6 +84,8 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
8184
hasPyBinary = true
8285
} else if !hasPyTestFile && f == pyTestEntrypointFilename {
8386
hasPyTestFile = true
87+
} else if f == conftestFilename {
88+
hasConftestFile = true
8489
} else if strings.HasSuffix(f, "_test.py") || (strings.HasPrefix(f, "test_") && ext == ".py") {
8590
pyTestFilenames.Add(f)
8691
} else if ext == ".py" {
@@ -196,10 +201,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
196201

197202
pyLibraryTargetName := cfg.RenderLibraryName(packageName)
198203

199-
// Check if a target with the same name we are generating alredy exists,
200-
// and if it is of a different kind from the one we are generating. If
201-
// so, we have to throw an error since Gazelle won't generate it
202-
// correctly.
204+
// Check if a target with the same name we are generating already
205+
// exists, and if it is of a different kind from the one we are
206+
// generating. If so, we have to throw an error since Gazelle won't
207+
// generate it correctly.
203208
if args.File != nil {
204209
for _, t := range args.File.Rules {
205210
if t.Name() == pyLibraryTargetName && t.Kind() != pyLibraryKind {
@@ -233,10 +238,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
233238

234239
pyBinaryTargetName := cfg.RenderBinaryName(packageName)
235240

236-
// Check if a target with the same name we are generating alredy exists,
237-
// and if it is of a different kind from the one we are generating. If
238-
// so, we have to throw an error since Gazelle won't generate it
239-
// correctly.
241+
// Check if a target with the same name we are generating already
242+
// exists, and if it is of a different kind from the one we are
243+
// generating. If so, we have to throw an error since Gazelle won't
244+
// generate it correctly.
240245
if args.File != nil {
241246
for _, t := range args.File.Rules {
242247
if t.Name() == pyBinaryTargetName && t.Kind() != pyBinaryKind {
@@ -267,6 +272,43 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
267272
result.Imports = append(result.Imports, pyBinary.PrivateAttr(config.GazelleImportsKey))
268273
}
269274

275+
var conftest *rule.Rule
276+
if hasConftestFile {
277+
deps, err := parser.parseSingle(conftestFilename)
278+
if err != nil {
279+
log.Fatalf("ERROR: %v\n", err)
280+
}
281+
282+
// Check if a target with the same name we are generating already
283+
// exists, and if it is of a different kind from the one we are
284+
// generating. If so, we have to throw an error since Gazelle won't
285+
// generate it correctly.
286+
if args.File != nil {
287+
for _, t := range args.File.Rules {
288+
if t.Name() == conftestTargetname && t.Kind() != pyLibraryKind {
289+
fqTarget := label.New("", args.Rel, conftestTargetname)
290+
err := fmt.Errorf("failed to generate target %q of kind %q: "+
291+
"a target of kind %q with the same name already exists.",
292+
fqTarget.String(), pyLibraryKind, t.Kind())
293+
collisionErrors.Add(err)
294+
}
295+
}
296+
}
297+
298+
conftestTarget := newTargetBuilder(pyLibraryKind, conftestTargetname, pythonProjectRoot, args.Rel).
299+
setUUID(uuid.Must(uuid.NewUUID()).String()).
300+
addSrc(conftestFilename).
301+
addModuleDependencies(deps).
302+
addVisibility(visibility).
303+
setTestonly().
304+
generateImportsAttribute()
305+
306+
conftest = conftestTarget.build()
307+
308+
result.Gen = append(result.Gen, conftest)
309+
result.Imports = append(result.Imports, conftest.PrivateAttr(config.GazelleImportsKey))
310+
}
311+
270312
if hasPyTestFile || hasPyTestTarget {
271313
if hasPyTestFile {
272314
// Only add the pyTestEntrypointFilename to the pyTestFilenames if
@@ -280,10 +322,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
280322

281323
pyTestTargetName := cfg.RenderTestName(packageName)
282324

283-
// Check if a target with the same name we are generating alredy exists,
284-
// and if it is of a different kind from the one we are generating. If
285-
// so, we have to throw an error since Gazelle won't generate it
286-
// correctly.
325+
// Check if a target with the same name we are generating already
326+
// exists, and if it is of a different kind from the one we are
327+
// generating. If so, we have to throw an error since Gazelle won't
328+
// generate it correctly.
287329
if args.File != nil {
288330
for _, t := range args.File.Rules {
289331
if t.Name() == pyTestTargetName && t.Kind() != pyTestKind {
@@ -317,6 +359,10 @@ func (py *Python) GenerateRules(args language.GenerateArgs) language.GenerateRes
317359
pyTestTarget.addModuleDependency(module{Name: pyLibrary.PrivateAttr(uuidKey).(string)})
318360
}
319361

362+
if conftest != nil {
363+
pyTestTarget.addModuleDependency(module{Name: conftest.PrivateAttr(uuidKey).(string)})
364+
}
365+
320366
pyTest := pyTestTarget.build()
321367

322368
result.Gen = append(result.Gen, pyTest)

‎gazelle/target.go

Copy file name to clipboardExpand all lines: gazelle/target.go
+10Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ type targetBuilder struct {
2222
visibility *treeset.Set
2323
main *string
2424
imports []string
25+
testonly bool
2526
}
2627

2728
// newTargetBuilder constructs a new targetBuilder.
@@ -96,6 +97,12 @@ func (t *targetBuilder) setMain(main string) *targetBuilder {
9697
return t
9798
}
9899

100+
// setTestonly sets the testonly attribute to true.
101+
func (t *targetBuilder) setTestonly() *targetBuilder {
102+
t.testonly = true
103+
return t
104+
}
105+
99106
// generateImportsAttribute generates the imports attribute.
100107
// These are a list of import directories to be added to the PYTHONPATH. In our
101108
// case, the value we add is on Bazel sub-packages to be able to perform imports
@@ -131,6 +138,9 @@ func (t *targetBuilder) build() *rule.Rule {
131138
if !t.deps.Empty() {
132139
r.SetPrivateAttr(config.GazelleImportsKey, t.deps)
133140
}
141+
if t.testonly {
142+
r.SetAttr("testonly", true)
143+
}
134144
r.SetPrivateAttr(resolvedDepsKey, t.resolvedDeps)
135145
return r
136146
}
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
load("@rules_python//python:defs.bzl", "py_library")
+27Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
load("@rules_python//python:defs.bzl", "py_library", "py_test")
2+
3+
py_library(
4+
name = "simple_test_with_conftest",
5+
srcs = [
6+
"__init__.py",
7+
"foo.py",
8+
],
9+
visibility = ["//:__subpackages__"],
10+
)
11+
12+
py_library(
13+
name = "conftest",
14+
testonly = True,
15+
srcs = ["conftest.py"],
16+
visibility = ["//:__subpackages__"],
17+
)
18+
19+
py_test(
20+
name = "simple_test_with_conftest_test",
21+
srcs = ["__test__.py"],
22+
main = "__test__.py",
23+
deps = [
24+
":conftest",
25+
":simple_test_with_conftest",
26+
],
27+
)
+4Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
# Simple test with conftest.py
2+
3+
This test case asserts that a simple `py_test` is generated as expected when a
4+
`conftest.py` is present.
+1Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This is a Bazel workspace for the Gazelle test data.
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
from foo import foo
2+
3+
_ = foo
+12Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import unittest
2+
3+
from __init__ import foo
4+
5+
6+
class FooTest(unittest.TestCase):
7+
def test_foo(self):
8+
self.assertEqual("foo", foo())
9+
10+
11+
if __name__ == "__main__":
12+
unittest.main()

‎gazelle/testdata/simple_test_with_conftest/conftest.py

Copy file name to clipboardExpand all lines: gazelle/testdata/simple_test_with_conftest/conftest.py
Whitespace-only changes.
+2Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
def foo():
2+
return "foo"
+3Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
---
2+
expect:
3+
exit_code: 0

0 commit comments

Comments
0 (0)
Morty Proxy This is a proxified and sanitized view of the page, visit original site.