Skip to content

Commit b203f9b

Browse files
authored
Merge pull request #1143 from nellh/git-hook-support
Add --filenames option to validate filenames from stdin
2 parents dbe089e + 4eae883 commit b203f9b

File tree

4 files changed

+114
-2
lines changed

4 files changed

+114
-2
lines changed

bids-validator/bin/bids-validator

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
process.title = 'bids-validator'
44

5-
var argv = require('yargs')
5+
const argv = require('yargs')
66
.usage('Usage: $0 <dataset_directory> [options]')
77
.help('help')
88
.alias('help', 'h')
@@ -50,6 +50,13 @@ var argv = require('yargs')
5050
'Optional configuration file. See https://github.com/bids-standard/bids-validator for more info',
5151
default: '.bids-validator-config.json',
5252
})
53+
.boolean('filenames')
54+
.default('filenames', false)
55+
.describe(
56+
'filenames',
57+
'A less accurate check that reads filenames one per line from stdin.',
58+
)
59+
.hide('filenames')
5360
.epilogue(
5461
'This tool checks if a dataset in a given directory is \
5562
compatible with the Brain Imaging Data Structure specification. To learn \

bids-validator/cli.js

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import validate from './index.js'
55
const format = validate.consoleFormat
66
import colors from 'colors/safe'
77
import fs from 'fs'
8-
import remoteFiles from './utils/files/remoteFiles'
8+
import { filenamesOnly } from './utils/filenamesOnly.js'
99

1010
const exitProcess = issues => {
1111
if (
@@ -51,6 +51,10 @@ export default function(dir, options) {
5151
process.exit(3)
5252
})
5353

54+
if (options.filenames) {
55+
return filenamesOnly()
56+
}
57+
5458
if (fs.existsSync(dir)) {
5559
if (options.json) {
5660
validate.BIDS(dir, options, function(issues, summary) {
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import { validateFilenames } from '../filenamesOnly.js'
2+
3+
describe('test filenames mode', () => {
4+
beforeEach(() => {
5+
console.log = jest.fn()
6+
})
7+
it('throws an error when obviously non-BIDS input', async () => {
8+
async function* badData() {
9+
yield 'nope'
10+
yield 'not-bids'
11+
yield 'data'
12+
}
13+
const res = await validateFilenames(badData())
14+
expect(res).toBe(false)
15+
})
16+
it('passes validation with a simple dataset', async () => {
17+
async function* goodData() {
18+
yield 'CHANGES'
19+
yield 'dataset_description.json'
20+
yield 'participants.tsv'
21+
yield 'README'
22+
yield 'sub-01/anat/sub-01_T1w.nii.gz'
23+
yield 'T1w.json'
24+
}
25+
const res = await validateFilenames(goodData())
26+
expect(res).toBe(true)
27+
})
28+
})
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/**
2+
* Run validation against a list of input files from git pre-receive
3+
*/
4+
import readline from 'readline'
5+
import path from 'path'
6+
import { promisify } from 'util'
7+
import consoleFormat from './consoleFormat'
8+
import quickTest from '../validators/bids/quickTest'
9+
import fullTest from '../validators/bids/fullTest'
10+
11+
// Disable most tests that might access files
12+
const defaultOptions = {
13+
ignoreWarnings: true,
14+
ignoreNiftiHeaders: true,
15+
ignoreSymlinks: true,
16+
ignoreSubjectConsistency: true,
17+
verbose: false,
18+
gitTreeMode: false,
19+
remoteFiles: false,
20+
gitRef: 'HEAD',
21+
config: { ignore: [44], warn: [], error: [], ignoredFiles: [] },
22+
}
23+
24+
async function generateFileObjects(stream) {
25+
const inputFiles = {}
26+
let index = 0
27+
for await (const line of stream) {
28+
const rootPath = `/${line}`
29+
/**
30+
* Simulated file object based on input
31+
* File size is 1 to prevent 0 size errors but makes some checks inaccurate
32+
*/
33+
const file = {
34+
name: path.basename(line),
35+
path: rootPath,
36+
relativePath: rootPath,
37+
size: 1,
38+
}
39+
inputFiles[index] = file
40+
index++
41+
}
42+
return inputFiles
43+
}
44+
45+
export async function validateFilenames(stream) {
46+
const inputFiles = await generateFileObjects(stream)
47+
const couldBeBIDS = quickTest(inputFiles)
48+
if (couldBeBIDS) {
49+
await new Promise(resolve => {
50+
fullTest(inputFiles, defaultOptions, false, '/dev/null', function(
51+
issues,
52+
summary,
53+
) {
54+
console.log(consoleFormat.issues(issues, defaultOptions) + '\n')
55+
console.log(consoleFormat.summary(summary, defaultOptions))
56+
resolve()
57+
})
58+
})
59+
return true
60+
} else {
61+
console.log(
62+
'This dataset failed a quick validation, please verify it is a BIDS dataset at the root of the git repository',
63+
)
64+
return false
65+
}
66+
}
67+
68+
export async function filenamesOnly() {
69+
const rl = readline.createInterface({
70+
input: process.stdin,
71+
})
72+
validateFilenames(rl)
73+
}

0 commit comments

Comments
 (0)