diff --git a/bids-validator/src/files/browser.ts b/bids-validator/src/files/browser.ts index 256f5c46f..4a52b1dcf 100644 --- a/bids-validator/src/files/browser.ts +++ b/bids-validator/src/files/browser.ts @@ -55,7 +55,11 @@ export async function fileListToTree(files: File[]): Promise { const tree = filesToTree(files.map((f) => new BIDSFileBrowser(f, ignore, root))) const bidsignore = tree.get('.bidsignore') if (bidsignore) { - ignore.add(await readBidsIgnore(bidsignore as BIDSFile)) + try { + ignore.add(await readBidsIgnore(bidsignore as BIDSFile)) + } catch (err) { + console.log(`Failed to read '.bidsignore' file with the following error:\n${err}`) + } } return tree } diff --git a/bids-validator/src/files/deno.ts b/bids-validator/src/files/deno.ts index a74adca58..3793c2c0d 100644 --- a/bids-validator/src/files/deno.ts +++ b/bids-validator/src/files/deno.ts @@ -6,6 +6,7 @@ import * as posix from '@std/path/posix' import { type BIDSFile, FileTree } from '../types/filetree.ts' import { requestReadPermission } from '../setup/requestPermissions.ts' import { FileIgnoreRules, readBidsIgnore } from './ignore.ts' +import { logger } from '../utils/logger.ts' /** * Thrown when a text file is decoded as UTF-8 but contains UTF-16 characters @@ -119,7 +120,7 @@ async function _readFileTree( ): Promise { await requestReadPermission() const name = basename(relativePath) - const tree = new FileTree(relativePath, name, parent) + const tree = new FileTree(relativePath, name, parent, ignore) for await (const dirEntry of Deno.readDir(join(rootPath, relativePath))) { if (dirEntry.isFile || dirEntry.isSymlink) { @@ -129,10 +130,6 @@ async function _readFileTree( ignore, ) file.parent = tree - // For .bidsignore, read in immediately and add the rules - if (dirEntry.name === '.bidsignore') { - ignore.add(await readBidsIgnore(file)) - } tree.files.push(file) } if (dirEntry.isDirectory) { @@ -151,7 +148,19 @@ async function _readFileTree( /** * Read in the target directory structure and return a FileTree */ -export function readFileTree(rootPath: string): Promise { +export async function readFileTree(rootPath: string): Promise { const ignore = new FileIgnoreRules([]) + try { + const ignoreFile = new BIDSFileDeno( + rootPath, + '.bidsignore', + ignore, + ) + ignore.add(await readBidsIgnore(ignoreFile)) + } catch (err) { + if (!Object.hasOwn(err, 'code') || err.code !== 'ENOENT') { + logger.error(`Failed to read '.bidsignore' file with the following error:\n${err}`) + } + } return _readFileTree(rootPath, '/', ignore) } diff --git a/bids-validator/src/schema/applyRules.ts b/bids-validator/src/schema/applyRules.ts index ba1a4c8d7..7d9ed80a4 100644 --- a/bids-validator/src/schema/applyRules.ts +++ b/bids-validator/src/schema/applyRules.ts @@ -221,7 +221,7 @@ function evalJsonCheck( } if (sidecarRule && !(keyName in context.sidecarKeyOrigin)) { - logger.warning( + logger.warn( `sidecarKeyOrigin map failed to initialize for ${context.path} on key ${keyName}. Validation caching not active for this key.`, ) } diff --git a/bids-validator/src/schema/context.ts b/bids-validator/src/schema/context.ts index 4bee2f1d2..75c37bd7b 100644 --- a/bids-validator/src/schema/context.ts +++ b/bids-validator/src/schema/context.ts @@ -225,7 +225,7 @@ export class BIDSContext implements Context { if (error.key) { this.dataset.issues.add({ code: error.key, location: this.file.path }) } - logger.warning( + logger.warn( `tsv file could not be opened by loadColumns '${this.file.path}'`, ) logger.debug(error) diff --git a/bids-validator/src/types/filetree.ts b/bids-validator/src/types/filetree.ts index 0e46c3f1e..a250e2cc6 100644 --- a/bids-validator/src/types/filetree.ts +++ b/bids-validator/src/types/filetree.ts @@ -1,3 +1,5 @@ +import { FileIgnoreRules } from '../files/ignore.ts' + export interface BIDSFile { // Filename name: string @@ -29,18 +31,22 @@ export class FileTree { name: string files: BIDSFile[] directories: FileTree[] - ignored: boolean viewed: boolean parent?: FileTree + #ignore: FileIgnoreRules - constructor(path: string, name: string, parent?: FileTree, ignored?: boolean) { + constructor(path: string, name: string, parent?: FileTree, ignore?: FileIgnoreRules) { this.path = path this.files = [] this.directories = [] this.name = name this.parent = parent this.viewed = false - this.ignored = ignored || false + this.#ignore = ignore ?? new FileIgnoreRules([]) + } + + get ignored(): boolean { + return this.#ignore.test(this.path) } _get(parts: string[]): BIDSFile | FileTree | undefined { diff --git a/bids-validator/src/validators/bids.ts b/bids-validator/src/validators/bids.ts index 5b0d96510..58f693db2 100644 --- a/bids-validator/src/validators/bids.ts +++ b/bids-validator/src/validators/bids.ts @@ -70,6 +70,9 @@ export async function validate( const bidsDerivatives: FileTree[] = [] const nonstdDerivatives: FileTree[] = [] fileTree.directories = fileTree.directories.filter((dir) => { + if (['sourcedata', 'code'].includes(dir.name)) { + return false + } if (dir.name !== 'derivatives') { return true } diff --git a/bids-validator/src/validators/json.ts b/bids-validator/src/validators/json.ts index 56b5c6ffa..af10f0dca 100644 --- a/bids-validator/src/validators/json.ts +++ b/bids-validator/src/validators/json.ts @@ -10,7 +10,7 @@ export const compile = memoize(metadataValidator.compile.bind(metadataValidator) export function setCustomMetadataFormats(schema: Schema): void { if (typeof schema.objects.formats !== 'object') { - logger.warning( + logger.warn( `schema.objects.formats missing from schema, format validation disabled.`, ) return @@ -19,7 +19,7 @@ export function setCustomMetadataFormats(schema: Schema): void { for (const key of Object.keys(schemaFormats)) { const pattern = schemaFormats[key]['pattern'] if (typeof pattern !== 'string') { - logger.warning( + logger.warn( `schema.objects.formats.${key} pattern missing or invalid. Skipping this format for addition to context json validator`, ) continue