Skip to content

Commit 25f0491

Browse files
authored
Minor meta-recipe features (#49)
* Add prediction to dir-path for meta-recipes using and ID * New unit tests for predict-path with 'dir-path' and 'id' arguments for meta-recipes * Update search results for meta-recipes * Unit test for searching for meta-recipes * Update version to 1.1.1
1 parent 818421d commit 25f0491

File tree

5 files changed

+195
-55
lines changed

5 files changed

+195
-55
lines changed

ggd/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
__version__ = "1.1.0"
1+
__version__ = "1.1.1"
22

ggd/predict_path.py

Lines changed: 79 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -18,31 +18,53 @@ def add_predict_path(p):
1818
help="Predict the install file path of a data package that hasn't been installed yet. (Use for workflows, such as Snakemake)",
1919
description="Get a predicted install file path for a data package before it is installed. (Use for workflows, such as Snakemake)",
2020
)
21+
2122
c.add_argument(
2223
"-c",
2324
"--channel",
2425
default="genomics",
2526
choices=[str(x) for x in get_ggd_channels()],
2627
help="The ggd channel of the recipe to find. (Default = genomics)",
28+
2729
)
2830
c.add_argument(
2931
"--prefix",
3032
default=None,
3133
help="(Optional) The name or the full directory path to an conda environment. The predicted path will be based on this conda environment. When installing, the data package should also be installed in this environment. (Only needed if not predicting for a path in the current conda environment)",
3234
)
33-
c2 = c.add_argument_group("required arguments")
35+
36+
c.add_argument(
37+
"--id",
38+
metavar="meta-recipe ID",
39+
default = None,
40+
help = "(Optional) The ID to predict the path for if the package is a meta-recipe. If it is not a meta-recipe it will be ignored"
41+
)
42+
43+
c2 = c.add_argument_group("One Argument Required")
44+
3445
c2.add_argument(
35-
"-pn",
36-
"--package-name",
37-
required=True,
38-
help="(Required) The name of the data package to predict a file path for",
46+
47+
"--dir-path",
48+
action="store_true",
49+
help = "(Required if '--file-name' not used) Whether or not to get the predicted directory path rather then the predicted file path. If both --file-name and --dir-path are provided the --file-name will be used and --dir-path will be ignored",
3950
)
51+
4052
c2.add_argument(
4153
"-fn",
4254
"--file-name",
55+
default = None,
56+
help="(Required if '--dir-path' not used) The name of the file to predict that path for. It is best if you give the full and correct name of the file to predict the path for. If not, ggd will try to identify the right file, but won't guarantee that it is the right file",
57+
)
58+
59+
c3 = c.add_argument_group("Required Arguments")
60+
61+
c3.add_argument(
62+
"-pn",
63+
"--package-name",
4364
required=True,
44-
help="(Required) The name of the file to predict that path for. It is best if you give the full and correct name of the file to predict the path for. If not, ggd will try to identify the right file, but won't guarantee that it is the right file",
65+
help="(Required) The name of the data package to predict a file path for",
4566
)
67+
4668
c.set_defaults(func=predict_path)
4769

4870

@@ -89,7 +111,12 @@ def predict_path(parser, args):
89111
import os
90112
import re
91113

92-
from .utils import conda_root, get_conda_prefix_path, prefix_in_conda
114+
from .utils import check_for_meta_recipes, conda_root, get_conda_prefix_path, prefix_in_conda
115+
from .install import get_idname_from_metarecipe
116+
117+
if not args.dir_path and args.file_name is None:
118+
print(":ggd:predict-path: !!ERROR!! Either the '--file-name' or the '--dir-path' argument is required. Neither was given")
119+
sys.exit()
93120

94121
## get prefix
95122
CONDA_ROOT = (
@@ -109,60 +136,68 @@ def predict_path(parser, args):
109136
)
110137
)
111138

112-
## Check there is a "final-files" in the metadata for the package
113-
if (
114-
"final-files" not in metadata_dict["packages"][args.package_name]["tags"]
115-
or len(
116-
metadata_dict["packages"][args.package_name]["tags"].get("final-files", [])
117-
)
118-
== 0
119-
):
120-
sys.exit(
121-
"\n:ggd:predict-path: The {p} data package does not have the final data files listed. This packages needs to be updated. To update, contact the GoGetData team at https://github.com/gogetdata/ggd-recipes\n".format(
122-
p=args.package_name
123-
)
124-
)
139+
if args.file_name is not None:
125140

126-
## Check that the file is one of the final-files listed in the metadata
127-
if (
128-
args.file_name
129-
not in metadata_dict["packages"][args.package_name]["tags"]["final-files"]
130-
):
131-
matching_files = [
132-
x
133-
for x in metadata_dict["packages"][args.package_name]["tags"]["final-files"]
134-
if re.search(args.file_name, x)
135-
]
136-
if len(matching_files) > 0:
137-
## Chose the first file that matched
138-
file_name = matching_files[0]
139-
else:
141+
## Check there is a "final-files" in the metadata for the package
142+
if (
143+
"final-files" not in metadata_dict["packages"][args.package_name]["tags"]
144+
or len(
145+
metadata_dict["packages"][args.package_name]["tags"].get("final-files", [])
146+
)
147+
== 0
148+
):
140149
sys.exit(
141-
"\n:ggd:predict-path: The {f} file is not one of the files listed for this package. The files installed by this package are: \n\t\t{fo}".format(
142-
f=args.file_name,
143-
fo="\n\t\t".join(
144-
metadata_dict["packages"][args.package_name]["tags"][
145-
"final-files"
146-
]
147-
),
150+
"\n:ggd:predict-path: The {p} data package does not have the final data files listed. This packages needs to be updated. To update, contact the GoGetData team at https://github.com/gogetdata/ggd-recipes\n".format(
151+
p=args.package_name
148152
)
149153
)
150-
else:
151-
file_name = args.file_name
154+
155+
## Check that the file is one of the final-files listed in the metadata
156+
if (
157+
args.file_name
158+
not in metadata_dict["packages"][args.package_name]["tags"]["final-files"]
159+
):
160+
matching_files = [
161+
x
162+
for x in metadata_dict["packages"][args.package_name]["tags"]["final-files"]
163+
if re.search(args.file_name, x)
164+
]
165+
if len(matching_files) > 0:
166+
## Chose the first file that matched
167+
file_name = matching_files[0]
168+
else:
169+
sys.exit(
170+
"\n:ggd:predict-path: The {f} file is not one of the files listed for this package. The files installed by this package are: \n\t\t{fo}".format(
171+
f=args.file_name,
172+
fo="\n\t\t".join(
173+
metadata_dict["packages"][args.package_name]["tags"][
174+
"final-files"
175+
]
176+
),
177+
)
178+
)
179+
else:
180+
file_name = args.file_name
181+
182+
elif args.dir_path:
183+
file_name = ""
184+
152185

153186
## Get path information
154187
species = metadata_dict["packages"][args.package_name]["identifiers"]["species"]
155188
build = metadata_dict["packages"][args.package_name]["identifiers"]["genome-build"]
156189
version = metadata_dict["packages"][args.package_name]["version"]
157190

191+
name = args.package_name if not check_for_meta_recipes(args.package_name, metadata_dict) else get_idname_from_metarecipe(args.id.lower(), args.package_name, metadata_dict) if args.id is not None else args.package_name
192+
158193
## Print the path
159194
path = os.path.join(
160195
CONDA_ROOT,
161196
"share",
162197
"ggd",
163198
species,
164199
build,
165-
args.package_name,
200+
name,
166201
version,
167202
file_name,
168203
)

ggd/search.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -461,7 +461,10 @@ def print_summary(search_terms, json_dict, match_list, installed_pkgs, installed
461461
% installed_paths[pkg]
462462
)
463463
else:
464-
results.append("\n\tTo install run:\n\t\tggd install %s" % pkg)
464+
from .utils import check_for_meta_recipes
465+
466+
results.append("\n\tTo install run:\n\t\tggd install %s %s" %(pkg, "--id <meta-recipe ID>" if check_for_meta_recipes(pkg,json_dict) else "" ))
467+
465468
print("\n\n".join(results))
466469
print("\n", dash)
467470

tests/test_info_scripts.py

Lines changed: 81 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1505,7 +1505,7 @@ def test_predict_path():
15051505
## Testing with grch37-autosomal-dominant-genes-berg-v1 data package
15061506

15071507
## Test bad package name
1508-
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz', package_name='bad_package_name-grch37-autosomal-dominant-genes-berg-v1', prefix=None)
1508+
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz', package_name='bad_package_name-grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
15091509

15101510
with pytest.raises(SystemExit) as pytest_wrapped_e:
15111511
predict_path.predict_path((), args)
@@ -1514,7 +1514,7 @@ def test_predict_path():
15141514

15151515

15161516
## Test bad file name
1517-
args = Namespace(channel='genomics', command='predict-path', file_name='autodom-genes-berg', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None)
1517+
args = Namespace(channel='genomics', command='predict-path', file_name='autodom-genes-berg', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
15181518

15191519
with pytest.raises(SystemExit) as pytest_wrapped_e:
15201520
predict_path.predict_path((), args)
@@ -1523,7 +1523,7 @@ def test_predict_path():
15231523

15241524

15251525
## Test closest file name
1526-
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None)
1526+
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
15271527

15281528
temp_stdout = StringIO()
15291529
with redirect_stdout(temp_stdout):
@@ -1533,7 +1533,7 @@ def test_predict_path():
15331533

15341534

15351535
## Test closest file name
1536-
args = Namespace(channel='genomics', command='predict-path', file_name='berg-v1.compliment', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None)
1536+
args = Namespace(channel='genomics', command='predict-path', file_name='berg-v1.compliment', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
15371537

15381538
temp_stdout = StringIO()
15391539
with redirect_stdout(temp_stdout):
@@ -1543,7 +1543,7 @@ def test_predict_path():
15431543

15441544

15451545
## Test full name file name
1546-
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None)
1546+
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
15471547

15481548
temp_stdout = StringIO()
15491549
with redirect_stdout(temp_stdout):
@@ -1552,6 +1552,17 @@ def test_predict_path():
15521552
assert os.path.join(utils.conda_root(),"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1","grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi") in str(output)
15531553

15541554

1555+
## Test no file-name or dir-path
1556+
args = Namespace(channel='genomics', command='predict-path', file_name=None, package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
1557+
1558+
temp_stdout = StringIO()
1559+
with pytest.raises(SystemExit) as pytest_wrapped_e, redirect_stdout(temp_stdout):
1560+
predict_path.predict_path((), args)
1561+
assert "SystemExit" in str(pytest_wrapped_e.exconly()) ## test that SystemExit was raised by sys.exit()
1562+
output = temp_stdout.getvalue().strip()
1563+
assert ":ggd:predict-path: !!ERROR!! Either the '--file-name' or the '--dir-path' argument is required. Neither was given" in output
1564+
1565+
15551566
## Test prdiction in different environmnet
15561567
### Temp conda environment
15571568
temp_env = os.path.join(utils.conda_root(), "envs", "predict-path")
@@ -1565,14 +1576,76 @@ def test_predict_path():
15651576
sp.check_output(["conda", "create", "--name", "predict-path"])
15661577

15671578
## Test full name file name
1568-
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=temp_env)
1579+
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=temp_env, dir_path = False, id = None)
1580+
1581+
temp_stdout = StringIO()
1582+
with redirect_stdout(temp_stdout):
1583+
predict_path.predict_path((), args)
1584+
output = temp_stdout.getvalue().strip()
1585+
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1","grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi") in str(output)
1586+
1587+
1588+
## Test full name file name and that the ID is ignored for a non meta-recipe
1589+
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=temp_env, dir_path = False, id = "SOME ID")
15691590

15701591
temp_stdout = StringIO()
15711592
with redirect_stdout(temp_stdout):
15721593
predict_path.predict_path((), args)
15731594
output = temp_stdout.getvalue().strip()
15741595
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1","grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi") in str(output)
15751596

1597+
1598+
## Test full name file name and dir-path. (File name should be used over dir path)
1599+
args = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=temp_env, dir_path = True, id = None)
1600+
1601+
temp_stdout = StringIO()
1602+
with redirect_stdout(temp_stdout):
1603+
predict_path.predict_path((), args)
1604+
output = temp_stdout.getvalue().strip()
1605+
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1","grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi") in str(output)
1606+
1607+
## Test dir path
1608+
args = Namespace(channel='genomics', command='predict-path', file_name=None, package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=temp_env, dir_path = True, id = None)
1609+
1610+
temp_stdout = StringIO()
1611+
with redirect_stdout(temp_stdout):
1612+
predict_path.predict_path((), args)
1613+
output = temp_stdout.getvalue().strip()
1614+
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1") in str(output)
1615+
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1","grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi") not in str(output)
1616+
1617+
1618+
## Test dir path and that the ID is ignored for a non meta-recipe
1619+
args = Namespace(channel='genomics', command='predict-path', file_name=None, package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=temp_env, dir_path = True, id = "SOME_ID")
1620+
1621+
temp_stdout = StringIO()
1622+
with redirect_stdout(temp_stdout):
1623+
predict_path.predict_path((), args)
1624+
output = temp_stdout.getvalue().strip()
1625+
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1") in str(output)
1626+
assert os.path.join(temp_env,"share","ggd", "Homo_sapiens","GRCh37","grch37-autosomal-dominant-genes-berg-v1","1","grch37-autosomal-dominant-genes-berg-v1.bed.gz.tbi") not in str(output)
1627+
1628+
1629+
## Test meta-recipe without an ID
1630+
args = Namespace(channel='genomics', command='predict-path', file_name=None, package_name='meta-recipe-geo-accession-geo-v1', prefix=temp_env, dir_path = True, id = None)
1631+
1632+
temp_stdout = StringIO()
1633+
with redirect_stdout(temp_stdout):
1634+
predict_path.predict_path((), args)
1635+
output = temp_stdout.getvalue().strip()
1636+
assert os.path.join(temp_env,"share","ggd", "meta-recipe","meta-recipe","meta-recipe-geo-accession-geo-v1","1") in str(output)
1637+
1638+
1639+
## Test meta-recipe with an ID and that the id is set to lower case
1640+
args = Namespace(channel='genomics', command='predict-path', file_name=None, package_name='meta-recipe-geo-accession-geo-v1', prefix=temp_env, dir_path = True, id = "GSE123")
1641+
1642+
temp_stdout = StringIO()
1643+
with redirect_stdout(temp_stdout):
1644+
predict_path.predict_path((), args)
1645+
output = temp_stdout.getvalue().strip()
1646+
assert os.path.join(temp_env,"share","ggd", "meta-recipe","meta-recipe","gse123-geo-v1","1") in str(output)
1647+
1648+
15761649
## Remove temp env created in test_get_environment_variables()
15771650
sp.check_output(["conda", "env", "remove", "--name", "predict-path"])
15781651
try:
@@ -1594,16 +1667,15 @@ def test_predict_path():
15941667
output = str(temp_stdout.getvalue().strip())
15951668
assert os.path.exists(str(output))
15961669

1597-
args2 = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None)
1670+
args2 = Namespace(channel='genomics', command='predict-path', file_name='grch37-autosomal-dominant-genes-berg-v1.bed.gz', package_name='grch37-autosomal-dominant-genes-berg-v1', prefix=None, dir_path = False, id = None)
15981671
temp_stdout = StringIO()
15991672
with redirect_stdout(temp_stdout):
16001673
predict_path.predict_path((), args2)
16011674
output2 = temp_stdout.getvalue().strip()
16021675

16031676
assert str(output2) == str(output)
16041677

1605-
args = Namespace(channel='genomics', command='uninstall', names=["grch37-autosomal-dominant-genes-berg-v1"])
1606-
uninstall.uninstall((),args)
1678+
sp.check_call(["ggd","uninstall","grch37-autosomal-dominant-genes-berg-v1"])
16071679

16081680

16091681
#--------------------------------------------------------

0 commit comments

Comments
 (0)