Allow different instances of build deps in environment#10792
Allow different instances of build deps in environment#10792becker33 merged 3 commits intospack:developfrom
Conversation
becker33
left a comment
There was a problem hiding this comment.
I would consider changing the all_deps booleans in to_node_dict and dag_hash to be named include_build_deps for clarity.
Similarly, I would consider changing _build_hash and _hash to something that's more descriptive of their differences. I think it might be hard for others to pick up this code, but I'm not sure what a better name for these two is so I'm not requesting changes since I don't have a good answer.
Overall LGTM.
There was a problem hiding this comment.
@scheibelp Does this mean we can get rid of the yaml round-trip at line 746 in environment.py?
tgamblin
left a comment
There was a problem hiding this comment.
@scheibelp @becker33: this looks mostly awesome -- I definitely think environments should be keyed by full hash. But this duplicates some work by @scottwittenburg on the release pipeline.
Requests:
- There is already a
full_hash()function onSpec, and we should consolidatebuild_hashinto that. - I have a clarifying question about whether the lockfile already includes the build dependencies -- see the comments.
- After reading the whole thing, I think it would probably be good to make the deptype arguments (
deptypes,all_deps) consistent and use the convention that we use when we havedeptypesas a keyword argument. I think it would improve the PR.
lib/spack/spack/environment.py
Outdated
|
|
||
| if read_lock_version == 1: | ||
| shutil.copy(self.lock_path, self._lock_backup_v1_path) | ||
| tty.debug("Storing backup of old lockfile format") |
There was a problem hiding this comment.
Add the path to the message here.
lib/spack/spack/environment.py
Outdated
| self.specs_by_hash = {} | ||
| for _, spec in specs_by_hash.items(): | ||
| old_hash = spec.dag_hash() | ||
| full_hash = spec.dag_hash(all_deps=True) |
There was a problem hiding this comment.
There is already a full_hash() method on Spec. Can we use this here? It's used for the release pipeline work by Kitware -- I think it's more consistent to just use the method since it's there, but it may not actually be what you want.
I'm looking at the full_hash() implementation and it looks like it mostly copies the dag_hash() code -- can it just be implemented as spec.dag_hash(all_deps=True)?
There was a problem hiding this comment.
In this case full_hash is just the dag hash computed with all dependencies (including build deps). Spec.full_hash includes Package.content_hash, which is more-specific than we have wanted so far and would be going a bit beyond the original fix.
Given that, I will rename this variable in this context to build_hash to avoid confusion.
There was a problem hiding this comment.
@scheibelp: ok thanks -- that is very clear and makes sense. Can we:
- Have 3 methods:
dag_hash(),full_hash(), andbuild_hash(), with comments making them clear, and - Implement
full_hashandbuild_hash()in terms ofdag_hash()? I think it would be clearer ifdag_hash()looked something like this:def dag_hash(self, length=none, deptypes=default_deptype, include_package=False): deptypes = canonical_deptype(deptypes) ...
Then implement full_hash and build_hash in terms of that. Does that seem clearer?
lib/spack/spack/spec.py
Outdated
| if deps: | ||
| if hash_function is None: | ||
| hash_function = lambda s: s.dag_hash() | ||
| hash_function = lambda s: s.dag_hash(all_deps=all_deps) |
There was a problem hiding this comment.
I found this hard to read because all_deps is not nearly as clear as the deptype argument that other functions have. I think it would be clearer that this is NOT the default case if we refactored to use deptype=....
lib/spack/spack/spec.py
Outdated
| node = s.to_node_dict(all_deps=all_deps) | ||
| node[s.name]['hash'] = s.dag_hash() | ||
| if all_deps: | ||
| node[s.name]['build_hash'] = s.dag_hash(all_deps=True) |
There was a problem hiding this comment.
I think this would be clearer with a deptype argument too.
|
@becker33 Regarding #10792 (review):
No: views still don't store build deps |
|
This could likely be compressed into two commits: everything up to and including a9a9466, and then everything after (refactoring the hash calculations). |
007201b to
30ca77c
Compare
|
@becker33: this is ready for re-review. There is at least one failing test, but I think it has to do with the rebase I did on top of I think that, barring any changes you want to the code, I can hand this off to you now. There are a few things I noticed here while working on this PR and the old |
|
@becker33: last point here. When merging this, we should probably squash everything before |
|
|
||
| # TODO: restore build dependencies here once we have less picky | ||
| # TODO: concretization. | ||
| if all_deps: |
There was a problem hiding this comment.
The comment above here should probably be removed now.
30ca77c to
672b600
Compare
|
@becker33: make sure my bugfix commit here is correct. I believe it fixes an issue in stacks. |
672b600 to
a6becb2
Compare
a6becb2 to
0843b13
Compare
- ensure that Spec._build_hash attr is defined - add logic to compute _build_hash when it is not already computed (e.g. for specs prior to this PR) - add test to ensure that different instance of a build dep are preserved - test conversion of old env lockfile format to new format - tests: avoid view creation, DAG display in tests using MockPackage - add regression test for more-general bug also fixed by this PR - update lockfile version since the way we are maintaining hashes has changed - write out backup for version-1 lockfiles and test that
Spack has evolved to have three types of hash functions, and it's becoming hard to tell when each one is called. Whlie we aren't yet ready to get rid of them, we can refactor them so that the code is clearer and easier to track. - Add a `hash_types` module with concise descriptors for hashes. - Consolidate hashing logic in a private `Spec._spec_hash()` function. - `dag_hash()`, `build_hash()`, and `full_hash()` all call `_spec_hash()` - `to_node_dict()`, `to_dict()`, `to_yaml()` and `to_json()` now take a `hash` parameter consistent with the one that `_spec_hash()` requires. Co-authored-by: Todd Gamblin <[email protected]>
- Setting specs from lockfiles was not correctly stringifying concretized user specs. - Fix `_set_user_specs_from_lockfile` - Add some validation code to `SpecList` constructor
0843b13 to
0bb00e3
Compare
This fixes a regression introduced in #10792. `spack uninstall` in an environment would not match concrete query specs properly after the index hash of enviroments changed. - [x] Search by DAG hash for specs to remove instead of by build hash
This fixes a regression introduced in #10792. `spack uninstall` in an environment would not match concrete query specs properly after the index hash of enviroments changed. - [x] Search by DAG hash for specs to remove instead of by build hash
This fixes a regression introduced in #10792. `spack uninstall` in an environment would not match concrete query specs properly after the index hash of enviroments changed. - [x] Search by DAG hash for specs to remove instead of by build hash
@tgamblin
Environments currently stores the full spec dag (including build dependencies) but indexes by dag hash, which excludes build dependencies. This can lead to reference errors for example given:
This PR