is there a way to exclude an arbitrary build targe...
# general
f
is there a way to exclude an arbitrary build target at runtime as if it never existed? ๐Ÿงต
Given https://github.com/pantsbuild/example-python/, here are all the targets:
Copy code
$ pants list ::                     
//:_python-default_lockfile
//:reqs
//:reqs#ansicolors
//:reqs#pytest
//:reqs#setuptools
//:reqs#types-setuptools
//python-default.lock:_python-default_lockfile
//requirements.txt:reqs
helloworld:lib
helloworld:pex_binary
helloworld/__init__.py:lib
helloworld/main.py:lib
helloworld/greet:lib
helloworld/greet:tests
helloworld/greet:translations
helloworld/greet/__init__.py:lib
helloworld/greet/greeting.py:lib
helloworld/greet/greeting_test.py:tests
helloworld/translator:dist
helloworld/translator:lib
helloworld/translator:tests
helloworld/translator/__init__.py:lib
helloworld/translator/translator.py:lib
helloworld/translator/translator_test.py:tests
say I want to exclude
helloworld/greet:lib
as if it doesn't exist at all:
Copy code
-python_sources(
-    name="lib",
-    dependencies=[":translations"],
-)
now if I run the
test
goal I do get an error since the
python_sources
do not exist any longer:
Copy code
$ pants test helloworld/greet
13:22:30.32 [ERROR] Completed: Run Pytest - helloworld/greet/greeting_test.py:tests - failed (exit code 2).
...
Traceback:
/usr/lib64/python3.9/importlib/__init__.py:127: in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
helloworld/greet/greeting_test.py:4: in <module>
    from helloworld.greet.greeting import Greeter
E   ModuleNotFoundError: No module named 'helloworld.greet.greeting'
- generated xml file: /tmp/pants-sandbox-6oBsCG/helloworld.greet.greeting_test.py.tests.xml -
=========================== short test summary info ============================
ERROR helloworld/greet/greeting_test.py

โœ• helloworld/greet/greeting_test.py:tests failed in 0.29s.
Is there a way to exclude a build target like this without commenting it out in the BUILD file? ๐Ÿ˜„ Using
--tags
would work when selecting targets, same with `--filter`; here I want to exclude it from the dependency graph as if it didn't exist at all.
the closest I was able to get is to dynamically extend the Pants ignored list:
pants --pants-ignore="+['helloworld/greet/greeting.py']" test helloworld/greet
but this would only work for paths to files whereas I am interested in accessing the build targets, e.g.
pants --exclude="+['helloworld/greet:lib']" test helloworld/greet
Also
--pants-ignore="+['helloworld/greet/greeting.py']"
won't work if there's a
python_source
build target with the exact path:
Copy code
python_source(name="foo", source="helloworld/greet/greeting.py")
as Pants correctly complains about
InvalidFieldException
- a build target with the source must point to an existing file on disk
c
what are you trying to achieve? There's the transitive exclude for python distributions for instance
!!helloworld/greet:lib
(on the
dependencies
field) ought to exclude it from being part of the distribution..
f
thanks, Andreas!! The transitive excludes would indeed work if I could programmatically set it for all the build targets in the repo as I don't know who may end up depending on a target. If not, this would mean modifying BUILD files whereas I want to have something I could orchestrate at the command line using a flag. The use case: I have a build target that represents a Git ignored generated Python module (generated outside of Pants, in a local development environment). For some operations, I want to continue to ignore them (like when running tests), but for some they need to exist (like when querying dependencies because modules will be importing members from that generated module)
c
Ok, cool. Whacky-hacky idea. Put said targets in a
BUILD.ephemeral
file (or something else if it needs to not hit the default pattern of
BUILD.*
), then tweak the https://www.pantsbuild.org/2.19/reference/global-options#build_patterns to include/exclude this file as needed.
that is, you could have an alias for adding or removing this entry from the list of patterns..
f
this is awesome, Andreas, thank you! Works great. I didn't know you could have multiple BUILD files per directory and their contents would just be merged!!
๐Ÿ‘ 1
I'll make sure this is reflected in the documentation!!
I'll wait for a bit and then open an issue I think proposing to add the exclude semantics - essentially removing a node from the dependency graph, dynamically. Another huge use case is dependency graph explorations I've been busy with for the past year. Say you want to eradicate dependency on a library in your application. How difficult would it be? So you go and comment the import line in the application program, but then it's picked as a transitive dependency. You keep commenting out it in other places until you are done. But it's tedious. It would be helpful to say - imagine this library doesn't exist, how does my graph look better? I.e. do I still have lots of tests picked up after arbitrary change or not?