Skip to content

Commit 14c910d

Browse files
authored
Finish tests (#5)
* removed submodule * update tests
1 parent 2661f97 commit 14c910d

File tree

5 files changed

+328
-20
lines changed

5 files changed

+328
-20
lines changed

local_bids_validation/local.py

Lines changed: 151 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
from argparse import ArgumentParser
22
from bids_validator import BIDSValidator
3-
from os import walk, sep, listdir
3+
from os import walk, sep, listdir, path
44
from typing import Union
55
from pathlib import Path
66
import json
77
import subprocess
8+
import glob
9+
import sys
810

911

1012
def collect_data_set(curl_download_file):
@@ -24,8 +26,12 @@ def check_for_bids_validator_js():
2426

2527
def report_number_of_files_bids_validator_js_found(input_folder: Union[str, Path]) -> int:
2628
if check_for_bids_validator_js:
27-
# run the js bids validator on the folder
28-
js = subprocess.check_output(["bids-validator", str(input_folder), "--json"])
29+
try:
30+
# run the js bids validator on the folder
31+
js = subprocess.check_output(["bids-validator", str(input_folder), "--json"])
32+
except subprocess.CalledProcessError as e:
33+
js = e.output
34+
2935
validator_output = json.loads(js)
3036
totalFiles = validator_output.get('summary', {}).get('totalFiles')
3137
else:
@@ -54,7 +60,7 @@ def check_bids_valid(manifest: list) -> dict:
5460
validity = {}
5561
validator = BIDSValidator()
5662
for file in manifest:
57-
validity[str(file)] = {'ValidBids': validator.is_bids(str(file)), 'bidsignored': False}
63+
validity[str(file)] = {'ValidBIDS': validator.is_bids(str(file)), 'bidsignored': False}
5864
return validity
5965

6066

@@ -72,25 +78,160 @@ def collect_bidsignored(input_folder: Union[str, Path]) -> list:
7278
ignored = []
7379
print("No .bidsignore file found")
7480

81+
pop_index = []
82+
for entry in ignored:
83+
if entry.startswith('#'):
84+
pop_index.append(entry)
85+
elif entry == '':
86+
pop_index.append(entry)
87+
88+
for index in pop_index:
89+
ignored.remove(index)
90+
7591
return ignored
7692

7793

78-
def determine_if_file_is_ignored(validity: dict, bidsignore: list) -> dict:
94+
def expand_bids_ignored(ignored: list, root_path: Union[str, Path]) -> list:
95+
"""given a bidsignore file, expand the entries to include all files that match the pattern"""
96+
expanded_paths = []
97+
for entry in ignored:
98+
if '*' in entry:
99+
matching_paths = glob.glob(str(Path(root_path) / entry))
100+
for path in matching_paths:
101+
if Path(path).is_dir():
102+
# if the path is a directory, add a trailing slash
103+
for root, dirs, files in walk(path):
104+
for file in files:
105+
expanded_paths.append(str(Path(root) / file))
106+
if Path(path).is_file():
107+
expanded_paths.append(path)
108+
else:
109+
pass
110+
111+
# create a set from the expanded paths to remove duplicates
112+
expanded_paths = set(expanded_paths)
113+
114+
return list(expanded_paths)
115+
116+
117+
def determine_ignored_files(validity: dict, bidsignore: list, print_output=False) -> dict:
79118
"""
80119
Given a dict from check_bids_valid, determine if the valid file falls under the scope of the .bidsignore file
81120
"""
121+
common_path = path.commonpath(bidsignore)
122+
all_bids_ignored = expand_bids_ignored(bidsignore, common_path)
123+
124+
for key in validity.keys():
125+
for ignored in all_bids_ignored:
126+
if key in ignored:
127+
validity[key]['bidsignored'] = True
128+
129+
# count the number of valid but ignored files
130+
valid_and_ignored = []
131+
valid_bids_files = []
132+
valid_bids_files_not_ignored = []
133+
invalid_bids_files_and_ignored = []
134+
invalid_and_not_ignored = []
135+
82136
for k, v in validity.items():
83-
print(f"{k}: {v}")
137+
if v['ValidBIDS'] and v['bidsignored']:
138+
valid_and_ignored.append(k)
139+
if v['ValidBIDS']:
140+
valid_bids_files.append(k)
141+
if v['ValidBIDS'] and not v['bidsignored']:
142+
valid_bids_files_not_ignored.append(k)
143+
if not v['ValidBIDS'] and v['bidsignored']:
144+
invalid_bids_files_and_ignored.append(k)
145+
if not v['ValidBIDS'] and not v['bidsignored']:
146+
invalid_and_not_ignored.append(k)
147+
148+
output = {
149+
'valid_and_ignored': valid_and_ignored,
150+
'valid_bids_files': valid_bids_files,
151+
'valid_bids_files_not_ignored': valid_bids_files_not_ignored,
152+
'invalid_bids_files_and_ignored': invalid_bids_files_and_ignored,
153+
'invalid': invalid_and_not_ignored
154+
}
155+
156+
if print_output:
157+
for k, v in output.items():
158+
print(f"Found {len(v)} files that are {k}")
159+
for file in v:
160+
print(file)
161+
print("\n")
162+
163+
return output
164+
165+
166+
def run_all(bids_dir):
167+
"""
168+
Run all the functions in this module.
169+
"""
170+
manifest = make_manifest(bids_dir)
171+
bids_ignored = collect_bidsignored(bids_dir)
172+
check_if_valid = check_bids_valid(manifest)
173+
valid_bids_files = []
174+
invalid_bids_files = []
175+
for file, validity in check_if_valid.items():
176+
if validity['ValidBIDS']:
177+
valid_bids_files.append(file)
178+
if not validity['ValidBIDS']:
179+
invalid_bids_files.append(file)
180+
181+
num_bids_validator_found = report_number_of_files_bids_validator_js_found(bids_dir)
182+
183+
all_bids_ignored = expand_bids_ignored(bids_ignored, bids_dir)
184+
185+
for key in check_if_valid.keys():
186+
for ignored in all_bids_ignored:
187+
if key in ignored:
188+
check_if_valid[key]['bidsignored'] = True
84189

190+
file_lists = determine_ignored_files(check_if_valid, all_bids_ignored, print_output=True)
85191

192+
return file_lists
86193

87194
if __name__ == "__main__":
88195
parser = ArgumentParser()
89-
parser.add_argument("input-folder", help="input folder to check for bids files", type=str)
196+
parser.add_argument("input_folder", help="input folder to check for bids files", type=str)
197+
parser.add_argument("--show-valid-and-ignored", help="show all valid and ignored files", action="store_true")
198+
parser.add_argument("--show-valid-bids-files", help="show all valid bids files", action="store_true")
199+
parser.add_argument("--show-valid-bids-files-not-ignored", help="show all valid bids files that are not ignored",
200+
action="store_true")
201+
parser.add_argument("--show-invalid-bids-files-and-ignored", help="show all invalid bids files that are ignored",
202+
action="store_true")
203+
parser.add_argument("--show-invalid", help="show all invalid files", action="store_true")
204+
90205
args = parser.parse_args()
91206
manifest = make_manifest(args.input_folder)
92207
check_if_valid = check_bids_valid(manifest)
208+
bidsignore = collect_bidsignored(args.input_folder)
209+
if not bidsignore:
210+
print("Exiting")
211+
sys.exit(1)
212+
output = determine_ignored_files(check_if_valid, bidsignore, print_output=False)
213+
if not args.show_valid_and_ignored and not args.show_valid_bids_files and not args.show_valid_bids_files_not_ignored and not args.show_invalid_bids_files_and_ignored and not args.show_invalid:
214+
output = determine_ignored_files(check_if_valid, bidsignore, print_output=True)
215+
elif args.show_valid_and_ignored:
216+
print("Found the following valid and ignored files:")
217+
for file in output.get('valid_and_ignored'):
218+
print(file)
219+
elif args.show_valid_bids_files:
220+
print("Found the following valid bids files:")
221+
for file in output.get('valid_bids_files'):
222+
print(file)
223+
elif args.show_valid_bids_files_not_ignored:
224+
print("Found the following valid bids files that are not ignored:")
225+
for file in output.get('valid_bids_files_not_ignored'):
226+
print(file)
227+
elif args.show_invalid_bids_files_and_ignored:
228+
print("Found the following invalid bids files that are ignored:")
229+
for file in output.get('invalid_bids_files_and_ignored'):
230+
print(file)
231+
elif args.show_invalid:
232+
print("Found the following invalid and ignored files:")
233+
for file in output.get('invalid'):
234+
print(file)
235+
else:
236+
pass
93237

94-
95-
96-
print("stop")

poetry.lock

Lines changed: 97 additions & 3 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

pyproject.toml

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@ python = "^3.10"
1212
bids-validator = "^1.12.0"
1313

1414

15+
[tool.poetry.group.dev.dependencies]
16+
pytest = "^7.4.2"
17+
1518
[build-system]
1619
requires = ["poetry-core"]
1720
build-backend = "poetry.core.masonry.api"

0 commit comments

Comments
 (0)