Skip to content

Commit a03144b

Browse files
CMLivingstonStu Hood
authored andcommitted
Fix Single Address Exclude (#6366)
### Problem The git commit hook (and CI lint) will lint targets that own changed files. Transforming specs to single addresses is currently broken and causes a "did you mean error" to be thrown on specs that actually exist in an affected build file: ``` ResolveError: "main_py2" was not found in namespace "testprojects/src/python/interpreter_selection/python_3_selection_testing". Did you mean one of: :lib_py2 :lib_py23 :lib_py3 :main_py2 :main_py23 :main_py3 :test_py2 :test_py23 ``` This manifested after trying to make changes to a `testprojects` BUILD file, which is excluded in the CI/commit hook lint step: `./pants -q --exclude-target-regexp='testprojects/.*' --changed-parent=master lint` ### Solution Edit build_files.py to aggregate excluded addresses in addition to included ones and check that excluded addresses align with exclude logic so that the "did you mean" error only occurs when the spec actually doesn't exist. ### Result Changes to files in testprojects will not throw any "did you mean" errors in CI/commit hook lint invoked by the following command: `./pants -q --exclude-target-regexp='testprojects/.*' --changed-parent=master lint`
1 parent 7fb7c83 commit a03144b

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

src/python/pants/engine/build_files.py

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -235,13 +235,17 @@ def filter_for_tag(tag):
235235
include_target = wrap_filters(create_filters(specs.tags if specs.tags else '', filter_for_tag))
236236

237237
addresses = []
238+
addresses_to_exclude = []
238239
included = set()
239240
def include(address_families, predicate=None):
240241
matched = False
241242
for af in address_families:
242243
for (a, t) in af.addressables.items():
243244
if (predicate is None or predicate(a)):
244-
if include_target(t) and (not exclude_address(a.spec)):
245+
should_exclude_address = exclude_address(a.spec)
246+
if should_exclude_address:
247+
addresses_to_exclude.append(a)
248+
if include_target(t) and (not should_exclude_address):
245249
matched = True
246250
if a not in included:
247251
addresses.append(a)
@@ -270,7 +274,7 @@ def include(address_families, predicate=None):
270274
# spec.name here is generally the root node specified on commandline. equality here implies
271275
# a root node i.e. node specified on commandline.
272276
if not include([address_family], predicate=lambda a: a.target_name == spec.name):
273-
if len(addresses) == 0:
277+
if len(addresses) == 0 and len(addresses_to_exclude) == 0:
274278
_raise_did_you_mean(address_family, spec.name)
275279
elif type(spec) is AscendantAddresses:
276280
include(

tests/python/pants_test/engine/test_build_files.py

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,24 @@ def test_exclude_pattern(self):
9696
self.assertEqual(len(targets.dependencies), 1)
9797
self.assertEqual(targets.dependencies[0].spec, 'root:not_me')
9898

99+
def test_exclude_pattern_with_single_address(self):
100+
"""Test that single address targets are filtered based on exclude patterns."""
101+
spec = SingleAddress('root', 'not_me')
102+
address_mapper = AddressMapper(JsonParser(TestTable()))
103+
snapshot = Snapshot(DirectoryDigest('xx', 2),
104+
(Path('root/BUILD', File('root/BUILD')),))
105+
address_family = AddressFamily('root',
106+
{
107+
'not_me': ('root/BUILD', TargetAdaptor()),
108+
}
109+
)
110+
targets = run_rule(
111+
addresses_from_address_families, address_mapper, Specs([spec], exclude_patterns=tuple(['root.*'])),{
112+
(Snapshot, PathGlobs): lambda _: snapshot,
113+
(AddressFamily, Dir): lambda _: address_family,
114+
})
115+
self.assertEqual(len(targets.dependencies), 0)
116+
99117

100118
class ApacheThriftConfiguration(StructWithDeps):
101119
# An example of a mixed-mode object - can be directly embedded without a name or else referenced

0 commit comments

Comments
 (0)