Directive inheritance: laziness for the win#2623
Conversation
|
is there a way to specify which cmake is needed? Maybe a given package depends on |
|
@davydden: if the parent says |
|
@alalazo is on a roll here. |
| when = kwargs.get('when', pkg.name) | ||
| destination = kwargs.get('destination', "") | ||
| placement = kwargs.get('placement', None) | ||
| # Check if the path is relative |
There was a problem hiding this comment.
@alalazo: is there some chance that I can convince you to use blank lines before sub-parts of long sections of code?
| 'can\'t be an absolute path.\n' | ||
| message += "\tdestination : '{dest}\n'".format(dest=destination) | ||
| raise RuntimeError(message) | ||
| # Check if the path falls within the main package stage area |
| normalized_destination = os.path.normpath( | ||
| join_path(test_path, destination) | ||
| ) # Normalized absolute path | ||
| if test_path not in normalized_destination: |
i see. As long as it's un-conditional (does not depend on a variant), then the union of
i like the idea for sure. |
|
@tgamblin This PR was one of the best code-puzzle so far in Spack! 😄 |
|
@alalazo: It's a really good idea. I bet this actually makes loading package modules quite a bit faster. The original version relied on walking up the call stack to find the package scope, but this won't need to do that work. I'm a little sad because this was actually one of the original code puzzles in Spack -- how to make the DSL. But I think the lazy DSL is better 😄 |
|
@alalazo: it might also make it easier to implement conditional directive groupings -- something I had thought of a while ago but that @TomasPuverle recently suggested. e.g.: with satisfies('@3.6:'):
depends_on('foo')
depends_on('bar')
with satisfies('@3.8:'):
depends_on('baz')basically a way to factor out common |
| version('2.0', 'cdf266530fee8af87454f15feb619609') | ||
| version('1.5.2', '545f98923430369a6b046ef3632ef95c') | ||
| version('1.5.1', 'd774e4b5a0db5f0f171c4fc0aabfa14e') | ||
|
|
There was a problem hiding this comment.
If we just take a step back and think about it, it's insane how many packages we can install with almost no code. There are probably hundreds of would be Autotools and CMake packages that no longer need any special install method. #1186 might just go down as the biggest line saving PR in Spack history. I'm looking at this empty package and it's hard to think of anything else we could remove. Now if we could just get rid of that stupid license and from spack import *...
|
|
||
| import llnl.util.tty as tty | ||
| import spack.build_environment | ||
| import spack.directives |
There was a problem hiding this comment.
Why not just from spack import * like regular Packages?
There was a problem hiding this comment.
Just to track what we are importing from where. As we are in core I tried to avoid:
from XXX import *but if you think it's more readable, I have no objection changing it.
| # build-system class we are using | ||
| build_system_class = 'CMakePackage' | ||
|
|
||
| spack.directives.depends_on('cmake', type='build') |
There was a problem hiding this comment.
Why no just regular old depends_on? Seems more readable.
There was a problem hiding this comment.
We definitely want thing to be readable so that other users can write their own Package subclasses or understand what is already present.
There was a problem hiding this comment.
This comes with the comment above. Let me know if you want this changed.
There was a problem hiding this comment.
I think the narrow import is good but can you do from spack.directives import depends_on so this is readable?
lib/spack/spack/directives.py
Outdated
| ) | ||
| _directives_to_be_executed = [] | ||
|
|
||
| return super(DirectiveMetaMixin, meta).__new__(meta, name, bases, attr_dict) # NOQA: ignore=E501 |
lib/spack/spack/directives.py
Outdated
| pkg.versions[Version(ver)] = kwargs | ||
| # Store kwargs for the package to later with a fetch_strategy. | ||
| pkg.versions[Version(ver)] = kwargs | ||
| _directives_to_be_executed.append(_execute) |
There was a problem hiding this comment.
Could the directive decorator either:
- Pass this list in as a parameter (kind of like how
pkgwas passed in before)? or - Make directives return either something callable on a
Packageor a list of them?
Either of these would make it so that not all directives have to refer to a global, and they'd consolidate any use of globals to the directive definition. It would also make it clearer to potential contributors how they might write their own directive (as the interface would be clear from the structure).
There was a problem hiding this comment.
I went for solution number 2 and moved all the global variables into the meta-class, see 30ae175 . Let me know if you want further modifications here.
Do you want to merge this first or #2502 first?
I think this one is ready, while #2502 needs some work to fix the coverage. That said, I have no preference on the order and no hurry in having any of the two merged immediately.
…ming from directives into packages + lazy directives * _dep_types -> dependency_types * using a meta-class to inject directives into packages * directives are lazy fixes spack#2466
CMakePackage: importing names from spack.directives directives: wrap __new__ to respect pep8
directives: removed global variables in favor of class variables. Simplified the interface for directives (they return a callable on a package or a list of them).
ac4aaba to
30ae175
Compare
This PR should fix #2466 and without touching a lot of code. The basic ideas:
Meta.__init__time if the class being created comes from a package repository (if not it's just code that has been factored into a common base)This also means that
DictWrapperandinspect.stackare not used anymore, as we defer code execution to a later time wherepkgis already available.Currently this PR supports only single inheritanceModifications