boa
boa copied to clipboard
Easy file-tests macros
Some ideas for easier writing tests. Currently people do stuff like
- test -f $PREFIX/include/mamba/test.hpp # [unix]
- if not %LIBRARY_PREFIX%\include\mamba\test.hpp exit 1 # [win]
which is super error prone and hard to get right.
Ideas for "files" macros:
site-packages("mamba")-> checks that pythonX.X/site-packages/exists and has contents (at least one init.py) pymodule("mamba")-> checks that pythonX.X/site-packages/exists and has contents (at least one init.py) lib("libmamba", soversion="...")-> check that at leastlibmamba.so/libamamba.dylibis found inlib/, additionally check for so-versions that link to that, or for windows, check thatbin/libmamba.dllandlib/libmamba.libare thereinclude("mamba")-> check that include folderinclude/mamba/existsinclude("mamba/test.hpp") -> check that fileinclude/mamba/test.hpp` exists in package- `bin("mamba")
I am unsure about the following ones:
cmake_find("mamba")-> make sure that find_package("mamba") would workpkgconfig("mamba")-> make sure that pkgconfig mamba works
There are probably some good ideas to support other languages and their install prefixes. I don't know where R installs to?!
We can also use qualifiers to disallow any files outside those matched by the macros, except maybe files in /share or some other data-centric directory. That would give pretty strict control over the package content.
We probably want to express this as something like
- exists:
site-packages:
- mamba
pymodule:
- mamba
file:
- $LIBRARY_PREFIX/some/file
glob:
- "**/another/file"
This has the nice advantage that we can include it easily in our json schema and get completions / validations at the json schema level for correctness of the specifiction
I agree that @mariusvniekerk suggestion seems to be more straightforward
I believe would be better to rename site-packages to python_modules, maybe?
- I like the idea of the
cmake_findandpkgconfig - I'm not sure an existence macro for
site-packages/pymoduleis a common enough use case. Most packages should haveimportsspecified already from which you can guess which files should exist.
@chrisburr how do they specify the imports?
@chrisburr the idea would be to also check for files that should not be in the package (basically the inverse) and either strongly warn or error out if something is in there that shouldn't be. But we could totally implicitly use the imports tests to check that.
@CJ-Wright thats another test field where one can check that a python lib gets imported fine.
@wolfv There is always the option of using:
- exists:
file:
- $SP_DIR/mamba/__init__.py
for the one or two exceptions where importing isn't possible because it needs to have a propitiatory shared library available or something.
I think we'd need more than just checking that a single file is imported, we'd need to check that all expected files are imported properly. In the past conda-forge's recipes haven't handled this well, leading to a bunch of issues on that front (and why I went and used the files themselves rather than the import tests to determine what modules are available)
@CJ-Wright I'm not sure quite what you're referencing? In the example:
test:
imports:
- mamba
then roughly maps to the command python -c 'import mamba'. Is it that you want to explicitly check all submodules as well? i.e.
test:
imports:
- mamba
- mamba._version
- mamba.mamba
- mamba.mamba_env
- mamba.repoquery
- mamba.utils
I believe we should not test all submodules, or at least if the maintainer wants to they can do it using a separated command because a lot of packages they accidentally package the test as well, and on top of there are some projects which have optional dependencies, so it may result in some errors in one of the imports due to the missing of one optional dependency
Sorry, maybe I have the wrong context. I thought this was being brought up to help address the file clobbering problem, by testing that only the expected files were available and no other files got in. If this is not the goal then not testing submodules is fine, but if we are going to address the clobber issue we need to test all the files.
Well, IMO if you define a pymodule or import then you "own" that "prefix". It would also say that you are not allowed to have any other pymodules (e.g. you are not allowed to accidentally add requests). This way we could help developers prevent accidental clobbers (not deliberate ones, though).
So if you add pymodule("mamba") your package is allowed to put any files it wants under site-packages/mamba/**/* but not elsewhere.
Does that make more sense now, @CJ-Wright ? The current way of testing for positive or negative file existence in conda-build is really cumbersome and error prone.
I think that makes sense, although you will need to have the ability for carve outs, for instance for matplotlib
One other lint we could do when we have a more semantic way of testing for a shared library is to automatically strongly warn if there is no run-exports.
cmake_find("mamba") -> make sure that find_package("mamba") would work
On CMake, it would be convenient to be able to both check the existence of a CMake package, and of the CMake imported targets, something like:
cmake_find("Eigen3", "Eigen3::Eigen")
This is particular convenient for packages that automatically disable some targets if the dependency is not correctly found.