Skip to content

Commit 55c67cd

Browse files
authored
Merge pull request #839 from bids-standard/remote-files-option
Remote files option
2 parents 665c836 + a54e853 commit 55c67cd

File tree

6 files changed

+67
-41
lines changed

6 files changed

+67
-41
lines changed

bids-validator/.eslintrc.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
{
22
"plugins": ["prettier"],
33
"parserOptions": {
4-
"ecmaVersion": 2017,
4+
"ecmaVersion": 2018,
55
"sourceType": "module"
66
},
77
"env": {

bids-validator/bin/bids-validator

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,9 @@ var argv = require('yargs')
2525
'ignoreSymlinks',
2626
'Skip any symlinked directories when validating a dataset',
2727
)
28+
.boolean('remoteFiles')
29+
.describe('remoteFiles', 'Validate remote files.')
30+
.default('remoteFiles', false)
2831
.boolean('gitTreeMode')
2932
.describe(
3033
'gitTreeMode',

bids-validator/utils/files/readDir.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -352,7 +352,7 @@ function getBIDSIgnoreFileObjNode(dir) {
352352
var bidsIgnoreFileObj = null
353353
var path = dir + '/.bidsignore'
354354
if (fs.existsSync(path)) {
355-
bidsIgnoreFileObj = { path: path }
355+
bidsIgnoreFileObj = { path: path, stats: { size: null } }
356356
}
357357
return bidsIgnoreFileObj
358358
}

bids-validator/utils/files/testFile.js

Lines changed: 46 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
const fs = require('fs')
22
const Issue = require('../../utils/issues').Issue
33
const remoteFiles = require('./remoteFiles')
4+
const { getOptions } = require('../../utils/options')
45

56
/**
67
* Test File
@@ -10,52 +11,60 @@ const remoteFiles = require('./remoteFiles')
1011
* or null and stats if it is.
1112
*/
1213
function testFile(file, annexed, dir, callback) {
13-
fs.stat(file.path, function(statErr, stats) {
14-
if (statErr) {
14+
fs.access(file.path, function(accessErr) {
15+
if (!accessErr) {
16+
// accessible
17+
handleFsAccess(file, callback)
18+
} else {
19+
// inaccessible
1520
fs.lstat(file.path, function(lstatErr, lstats) {
16-
if (lstatErr) {
17-
callback(new Issue({ code: 44, file: file }), stats)
18-
} else if (lstats && lstats.isSymbolicLink()) {
19-
if (annexed) {
20-
// Set byte retrieval limits based on file type
21-
const limit = file.name.includes('.nii') ? 500 : false
22-
// Call process to get remote files
23-
// It will call callback with content or error
24-
remoteFiles.getAnnexedFile(file, dir, limit, callback)
25-
} else {
26-
callback(new Issue({ code: 43, file: file }), stats)
27-
}
21+
if (!lstatErr && lstats && lstats.isSymbolicLink()) {
22+
// symlink
23+
if (getOptions().remoteFiles)
24+
// only follow symlinks when --remoteFiles option is on
25+
handleRemoteAccess(file, annexed, dir, callback)
26+
else
27+
callback(
28+
new Issue({
29+
code: 114,
30+
file,
31+
}),
32+
file.stats,
33+
)
2834
} else {
29-
callback(new Issue({ code: 44, file: file }), stats)
35+
// inaccessible local file
36+
callback(new Issue({ code: 44, file: file }), file.stats)
3037
}
3138
})
32-
} else {
33-
fs.access(file.path, function(accessErr) {
34-
handleFsAccess(accessErr, file, stats, callback)
35-
})
3639
}
3740
})
3841
}
3942

40-
function handleFsAccess(accessErr, file, stats, callback) {
41-
if (!accessErr) {
42-
process.nextTick(function() {
43-
if (stats.size === 0) {
44-
callback(
45-
new Issue({
46-
code: 99,
47-
file: file,
48-
reason: `Empty files (${file.path}) not allowed.`,
49-
}),
50-
stats,
51-
)
52-
}
53-
callback(null, stats)
54-
})
43+
function handleFsAccess(file, callback) {
44+
process.nextTick(function() {
45+
if (file.stats.size === 0) {
46+
callback(
47+
new Issue({
48+
code: 99,
49+
file: file,
50+
reason: `Empty files (${file.path}) not allowed.`,
51+
}),
52+
file.stats,
53+
)
54+
}
55+
callback(null, file.stats)
56+
})
57+
}
58+
59+
function handleRemoteAccess(file, annexed, dir, callback) {
60+
if (annexed) {
61+
// Set byte retrieval limits based on file type
62+
const limit = file.name.includes('.nii') ? 500 : false
63+
// Call process to get remote files
64+
// It will call callback with content or error
65+
remoteFiles.getAnnexedFile(file, dir, limit, callback)
5566
} else {
56-
process.nextTick(function() {
57-
callback(new Issue({ code: 44, file: file }), stats)
58-
})
67+
callback(new Issue({ code: 43, file: file }), file.stats)
5968
}
6069
}
6170

bids-validator/utils/issues/list.js

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -632,4 +632,10 @@ module.exports = {
632632
reason:
633633
'The Authors field of dataset_description.json should contain an array of fields - with one author per field. This was triggered because there are no authors, which will make DOI registration from dataset metadata impossible.',
634634
},
635+
114: {
636+
key: 'INCOMPLETE_DATASET',
637+
severity: 'error',
638+
reason:
639+
'This dataset contains remote files. If you would like to validate with remote files, use the --remoteFiles option.',
640+
},
635641
}

bids-validator/utils/options.js

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,21 @@
11
var files = require('./files')
22
var json = require('./json')
33

4+
let options
5+
46
module.exports = {
57
/**
68
* Parse
79
*/
8-
parse: function(options, callback) {
9-
options = options ? options : {}
10+
parse: function(args, callback) {
11+
options = args ? args : {}
1012
options = {
1113
ignoreWarnings: Boolean(options.ignoreWarnings),
1214
ignoreNiftiHeaders: Boolean(options.ignoreNiftiHeaders),
1315
ignoreSymlinks: Boolean(options.ignoreSymlinks),
1416
verbose: Boolean(options.verbose),
1517
gitTreeMode: Boolean(options.gitTreeMode),
18+
remoteFiles: Boolean(options.remoteFiles),
1619
gitRef: options.gitRef || 'HEAD',
1720
config: options.config || {},
1821
}
@@ -26,6 +29,11 @@ module.exports = {
2629
}
2730
},
2831

32+
getOptions: () => {
33+
const readonlyOptions = Object.freeze({ ...options })
34+
return readonlyOptions
35+
},
36+
2937
/**
3038
* Load Config
3139
*/

0 commit comments

Comments
 (0)