Skip to content

Commit

Permalink
ENH: Create a pre-receive hook that accepts ignore rules and file lis…
Browse files Browse the repository at this point in the history
…ting
  • Loading branch information
effigies committed Feb 9, 2024
1 parent 365f321 commit 25897f3
Showing 1 changed file with 62 additions and 0 deletions.
62 changes: 62 additions & 0 deletions tools/schemacode/bidsschematools/__main__.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import logging
import os
import re
import sys
from itertools import chain

import click

from .rules import regexify_filename_rules
from .schema import export_schema, load_schema
from .validator import _bidsignore_check


@click.group()
Expand Down Expand Up @@ -32,5 +37,62 @@ def export(ctx, schema, output):
fobj.write(text)


@cli.command("pre-receive-hook")
@click.option("--schema", "-s", type=click.Path(), help="Path to the BIDS schema")
@click.option(
"--input", "-i", "input_", default="-", type=click.Path(), help="Input file (default: stdin)"
)
@click.option(
"--output",
"-o",
"output",
default="-",
type=click.Path(),
help="Output file (default: stdout)",
)
def pre_receive_hook(schema, input_, output):
"""Validate filenames from a list of files against the BIDS schema
The input should be a list of ignore patterns followed by a line containing
"0001" and then a list of filenames. The output will be a list of filenames
that do not match the schema.
This is intended to be used in a git pre-receive hook.
"""
# Slurp inputs for now; we can think about streaming later
if input_ == "-":
lines = sys.stdin.readlines()
else:
with open(input_) as fobj:
lines = fobj.readlines()

split = lines.index("0001\n")
ignore = [line.rstrip() for line in lines[:split]]
filenames = [line.rstrip() for line in lines[split + 1 :]]

schema = load_schema(schema)
all_rules = chain.from_iterable(
regexify_filename_rules(group, schema, level=2)
for group in (schema.rules.files.common, schema.rules.files.raw)
)
regexes = [rule["regex"] for rule in all_rules]
# XXX Hack for phenotype files - this can be removed once we
# have a schema definition for them
regexes.append(r"phenotype/.*\.tsv")

output = sys.stdout if output == "-" else open(output, "w")

rc = 0
with output:
for filename in filenames:
if any(_bidsignore_check(pattern, filename, "") for pattern in ignore):
continue
if not any(re.match(regex, filename) for regex in regexes):
output.write(f"{filename}\n")
rc = 1

sys.exit(rc)


if __name__ == "__main__":
cli()

0 comments on commit 25897f3

Please sign in to comment.