stacks: update environment add/remove algorithms
This commit is contained in:
parent
6cfbfcc967
commit
533a8d7c82
@ -674,73 +674,61 @@ def add(self, user_spec, list_name='specs'):
|
|||||||
elif not spack.repo.path.exists(spec.name):
|
elif not spack.repo.path.exists(spec.name):
|
||||||
raise SpackEnvironmentError('no such package: %s' % spec.name)
|
raise SpackEnvironmentError('no such package: %s' % spec.name)
|
||||||
|
|
||||||
added = False
|
list_to_change = self.read_specs[list_name]
|
||||||
existing = False
|
existing = str(spec) in list_to_change.yaml_list
|
||||||
for i, (name, speclist) in enumerate(self.read_specs.items()):
|
if not existing:
|
||||||
# Iterate over all named lists from an OrderedDict()
|
list_to_change.add(str(spec))
|
||||||
if name == list_name:
|
index = list(self.read_specs.keys()).index(list_name)
|
||||||
# We need to modify this list
|
|
||||||
# TODO: Add conditional which reimplements name-level checking
|
for i, (name, speclist) in enumerate(
|
||||||
existing = str(spec) in speclist.yaml_list
|
list(self.read_specs.items())[index + 1:], index + 1):
|
||||||
if not existing:
|
|
||||||
speclist.add(str(spec))
|
|
||||||
added = True
|
|
||||||
elif added:
|
|
||||||
# We've already modified a list, so all later lists need to
|
|
||||||
# have their references updated.
|
|
||||||
new_reference = dict((n, self.read_specs[n])
|
new_reference = dict((n, self.read_specs[n])
|
||||||
for n in list(self.read_specs.keys())[:i])
|
for n in list(self.read_specs.keys())[:i])
|
||||||
speclist.update_reference(new_reference)
|
speclist.update_reference(new_reference)
|
||||||
|
|
||||||
return bool(not existing)
|
return bool(not existing)
|
||||||
|
|
||||||
def remove(self, query_spec, list_name='specs', force=False):
|
def remove(self, query_spec, list_name='specs', force=False):
|
||||||
"""Remove specs from an environment that match a query_spec"""
|
"""Remove specs from an environment that match a query_spec"""
|
||||||
query_spec = Spec(query_spec)
|
query_spec = Spec(query_spec)
|
||||||
|
|
||||||
removed = False
|
list_to_change = self.read_specs[list_name]
|
||||||
for i, (name, speclist) in enumerate(self.read_specs.items()):
|
matches = []
|
||||||
# Iterate over all named lists from an OrderedDict()
|
|
||||||
if name == list_name:
|
|
||||||
# We need to modify this list
|
|
||||||
# try abstract specs first
|
|
||||||
matches = []
|
|
||||||
|
|
||||||
if not query_spec.concrete:
|
if not query_spec.concrete:
|
||||||
matches = [s for s in speclist if s.satisfies(query_spec)]
|
matches = [s for s in list_to_change if s.satisfies(query_spec)]
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
# concrete specs match against concrete specs in the env
|
# concrete specs match against concrete specs in the env
|
||||||
specs_hashes = zip(
|
specs_hashes = zip(
|
||||||
self.concretized_user_specs, self.concretized_order)
|
self.concretized_user_specs, self.concretized_order)
|
||||||
matches = [
|
matches = [
|
||||||
s for s, h in specs_hashes
|
s for s, h in specs_hashes
|
||||||
if query_spec.dag_hash() == h
|
if query_spec.dag_hash() == h
|
||||||
]
|
]
|
||||||
|
|
||||||
if not matches:
|
if not matches:
|
||||||
raise SpackEnvironmentError(
|
raise SpackEnvironmentError(
|
||||||
"Not found: {0}".format(query_spec))
|
"Not found: {0}".format(query_spec))
|
||||||
|
|
||||||
for spec in matches:
|
for spec in matches:
|
||||||
if spec in speclist:
|
if spec in list_to_change:
|
||||||
speclist.remove(spec)
|
list_to_change.remove(spec)
|
||||||
removed = True
|
|
||||||
|
|
||||||
if force and spec in self.concretized_user_specs:
|
if force and spec in self.concretized_user_specs:
|
||||||
i = self.concretized_user_specs.index(spec)
|
i = self.concretized_user_specs.index(spec)
|
||||||
del self.concretized_user_specs[i]
|
del self.concretized_user_specs[i]
|
||||||
|
|
||||||
dag_hash = self.concretized_order[i]
|
dag_hash = self.concretized_order[i]
|
||||||
del self.concretized_order[i]
|
del self.concretized_order[i]
|
||||||
del self.specs_by_hash[dag_hash]
|
del self.specs_by_hash[dag_hash]
|
||||||
removed = True
|
|
||||||
|
|
||||||
elif removed:
|
index = list(self.read_specs.keys()).index(list_name)
|
||||||
# We've already modified one list, so all later lists need
|
for i, (name, speclist) in enumerate(
|
||||||
# their references updated.
|
list(self.read_specs.items())[index + 1:], index + 1):
|
||||||
new_reference = dict((n, self.read_specs[n])
|
new_reference = dict((n, self.read_specs[n])
|
||||||
for n in list(self.read_specs.keys())[:i])
|
for n in list(self.read_specs.keys())[:i])
|
||||||
speclist.update_reference(new_reference)
|
speclist.update_reference(new_reference)
|
||||||
|
|
||||||
def concretize(self, force=False):
|
def concretize(self, force=False):
|
||||||
"""Concretize user_specs in this environment.
|
"""Concretize user_specs in this environment.
|
||||||
|
@ -136,7 +136,7 @@ def _expand_references(self, yaml):
|
|||||||
return ret
|
return ret
|
||||||
else:
|
else:
|
||||||
msg = 'SpecList %s refers to ' % self.name
|
msg = 'SpecList %s refers to ' % self.name
|
||||||
msg = 'named list %s ' % name
|
msg += 'named list %s ' % name
|
||||||
msg += 'which does not appear in its reference dict'
|
msg += 'which does not appear in its reference dict'
|
||||||
raise UndefinedReferenceError(msg)
|
raise UndefinedReferenceError(msg)
|
||||||
# No references in this
|
# No references in this
|
||||||
|
@ -827,6 +827,33 @@ def test_stack_yaml_remove_from_list(tmpdir):
|
|||||||
assert Spec('callpath') in test.user_specs
|
assert Spec('callpath') in test.user_specs
|
||||||
|
|
||||||
|
|
||||||
|
def test_stack_yaml_remove_from_list_force(tmpdir):
|
||||||
|
filename = str(tmpdir.join('spack.yaml'))
|
||||||
|
with open(filename, 'w') as f:
|
||||||
|
f.write("""\
|
||||||
|
env:
|
||||||
|
definitions:
|
||||||
|
- packages: [mpileaks, callpath]
|
||||||
|
specs:
|
||||||
|
- matrix:
|
||||||
|
- [$packages]
|
||||||
|
- [^mpich, ^zmpi]
|
||||||
|
""")
|
||||||
|
with tmpdir.as_cwd():
|
||||||
|
env('create', 'test', './spack.yaml')
|
||||||
|
with ev.read('test'):
|
||||||
|
concretize()
|
||||||
|
remove('-f', '-l', 'packages', 'mpileaks')
|
||||||
|
find_output = find('-c')
|
||||||
|
|
||||||
|
print find_output
|
||||||
|
assert False
|
||||||
|
test = ev.read('test')
|
||||||
|
|
||||||
|
assert Spec('mpileaks') not in test.user_specs
|
||||||
|
assert Spec('callpath') in test.user_specs
|
||||||
|
|
||||||
|
|
||||||
def test_stack_yaml_attempt_remove_from_matrix(tmpdir):
|
def test_stack_yaml_attempt_remove_from_matrix(tmpdir):
|
||||||
filename = str(tmpdir.join('spack.yaml'))
|
filename = str(tmpdir.join('spack.yaml'))
|
||||||
with open(filename, 'w') as f:
|
with open(filename, 'w') as f:
|
||||||
|
Loading…
Reference in New Issue
Block a user