Skip to content

Commit 38e01ba

Browse files
committed
Merge remote-tracking branch 'upstream/master' into md
2 parents fb91628 + 10dcb1b commit 38e01ba

File tree

2 files changed

+96
-6
lines changed

2 files changed

+96
-6
lines changed

paths_cli/commands/contents.py

Lines changed: 55 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,64 @@
11
import click
22
from paths_cli.parameters import INPUT_FILE
33

4+
UNNAMED_SECTIONS = ['steps', 'movechanges', 'samplesets', 'trajectories',
5+
'snapshots']
6+
7+
NAME_TO_ATTR = {
8+
'CVs': 'cvs',
9+
'Volumes': 'volumes',
10+
'Engines': 'engines',
11+
'Networks': 'networks',
12+
'Move Schemes': 'schemes',
13+
'Simulations': 'pathsimulators',
14+
'Tags': 'tags',
15+
'Steps': 'steps',
16+
'Move Changes': 'movechanges',
17+
'SampleSets': 'samplesets',
18+
'Trajectories': 'trajectories',
19+
'Snapshots': 'snapshots'
20+
}
21+
422
@click.command(
523
'contents',
624
short_help="list named objects from an OPS .nc file",
725
)
826
@INPUT_FILE.clicked(required=True)
9-
def contents(input_file):
27+
@click.option('--table', type=str, required=False,
28+
help="table to show results from")
29+
def contents(input_file, table):
1030
"""List the names of named objects in an OPS .nc file.
1131
1232
This is particularly useful when getting ready to use one of simulation
1333
scripts (i.e., to identify exactly how a state or engine is named.)
1434
"""
1535
storage = INPUT_FILE.get(input_file)
1636
print(storage)
37+
if table is None:
38+
report_all_tables(storage)
39+
else:
40+
table_attr = table.lower()
41+
try:
42+
store = getattr(storage, table_attr)
43+
except AttributeError:
44+
raise click.UsageError("Unknown table: '" + table_attr + "'")
45+
else:
46+
print(get_section_string(table_attr, store))
47+
48+
49+
def get_section_string(label, store):
50+
attr = NAME_TO_ATTR.get(label, label.lower())
51+
if attr in UNNAMED_SECTIONS:
52+
string = get_unnamed_section_string(label, store)
53+
elif attr in ['tag', 'tags']:
54+
string = get_section_string_nameable(label, store, _get_named_tags)
55+
else:
56+
string = get_section_string_nameable(label, store,
57+
_get_named_namedobj)
58+
return string
59+
60+
61+
def report_all_tables(storage):
1762
store_section_mapping = {
1863
'CVs': storage.cvs, 'Volumes': storage.volumes,
1964
'Engines': storage.engines, 'Networks': storage.networks,
@@ -26,12 +71,16 @@ def contents(input_file):
2671
print(get_section_string_nameable('Tags', storage.tags, _get_named_tags))
2772

2873
print("\nData Objects:")
29-
unnamed_sections = {
30-
'Steps': storage.steps, 'Move Changes': storage.movechanges,
31-
'SampleSets': storage.samplesets,
32-
'Trajectories': storage.trajectories, 'Snapshots': storage.snapshots
74+
data_object_mapping = {
75+
'Steps': lambda storage: storage.steps,
76+
'Move Changes': lambda storage: storage.movechanges,
77+
'SampleSets': lambda storage: storage.samplesets,
78+
'Trajectories': lambda storage: storage.trajectories,
79+
'Snapshots': lambda storage: storage.snapshots
3380
}
34-
for section, store in unnamed_sections.items():
81+
82+
for section, store_func in data_object_mapping.items():
83+
store = store_func(storage)
3584
print(get_unnamed_section_string(section, store))
3685

3786
def _item_or_items(count):

paths_cli/tests/commands/test_contents.py

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,44 @@ def test_contents(tps_fixture):
4040
assert results.output.split('\n') == expected
4141
for truth, beauty in zip(expected, results.output.split('\n')):
4242
assert truth == beauty
43+
44+
@pytest.mark.parametrize('table', ['volumes', 'trajectories', 'tags'])
45+
def test_contents_table(tps_fixture, table):
46+
scheme, network, engine, init_conds = tps_fixture
47+
runner = CliRunner()
48+
with runner.isolated_filesystem():
49+
storage = paths.Storage("setup.nc", 'w')
50+
for obj in tps_fixture:
51+
storage.save(obj)
52+
storage.tags['initial_conditions'] = init_conds
53+
54+
results = runner.invoke(contents, ['setup.nc', '--table', table])
55+
cwd = os.getcwd()
56+
expected = {
57+
'volumes': [
58+
f"Storage @ '{cwd}/setup.nc'",
59+
"volumes: 8 items", "* A", "* B", "* plus 6 unnamed items",
60+
""
61+
],
62+
'trajectories': [
63+
f"Storage @ '{cwd}/setup.nc'",
64+
"trajectories: 1 unnamed item",
65+
""
66+
],
67+
'tags': [
68+
f"Storage @ '{cwd}/setup.nc'",
69+
"tags: 1 item",
70+
"* initial_conditions",
71+
""
72+
],
73+
}[table]
74+
assert results.output.split("\n") == expected
75+
assert results.exit_code == 0
76+
77+
def test_contents_table_error():
78+
runner = CliRunner()
79+
with runner.isolated_filesystem():
80+
storage = paths.Storage("temp.nc", mode='w')
81+
storage.close()
82+
results = runner.invoke(contents, ['temp.nc', '--table', 'foo'])
83+
assert results.exit_code != 0

0 commit comments

Comments
 (0)