diff --git a/deno.json b/deno.json index 3bb916142..6133960f5 100644 --- a/deno.json +++ b/deno.json @@ -32,7 +32,7 @@ "@cliffy/command": "jsr:@effigies/cliffy-command@1.0.0-dev.8", "@cliffy/table": "jsr:@effigies/cliffy-table@1.0.0-dev.5", "@hed/validator": "npm:hed-validator@3.15.5", - "@ignore": "npm:ignore@6.0.2", + "@ignore": "npm:ignore@7.0.3", "@libs/xml": "jsr:@libs/xml@6.0.1", "@mango/nifti": "npm:@bids/nifti-reader-js@0.6.9", "@std/assert": "jsr:@std/assert@1.0.7", diff --git a/deno.lock b/deno.lock index 6248251c6..8ce3d233d 100644 --- a/deno.lock +++ b/deno.lock @@ -4,6 +4,7 @@ "jsr:@bids/schema@1.0.0": "1.0.0", "jsr:@cliffy/flags@1.0.0-rc.7": "1.0.0-rc.7", "jsr:@cliffy/internal@1.0.0-rc.7": "1.0.0-rc.7", + "jsr:@cliffy/table@1.0.0-rc.7": "1.0.0-rc.7", "jsr:@effigies/cliffy-command@1.0.0-dev.8": "1.0.0-dev.8", "jsr:@effigies/cliffy-table@1.0.0-dev.5": "1.0.0-dev.5", "jsr:@effigies/cliffy-table@^1.0.0-dev.5": "1.0.0-dev.5", @@ -38,7 +39,7 @@ "npm:@bids/nifti-reader-js@0.6.9": "0.6.9", "npm:ajv@8.17.1": "8.17.1", "npm:hed-validator@3.15.5": "3.15.5", - "npm:ignore@6.0.2": "6.0.2" + "npm:ignore@7.0.3": "7.0.3" }, "jsr": { "@bids/schema@1.0.0": { @@ -53,11 +54,18 @@ "@cliffy/internal@1.0.0-rc.7": { "integrity": "10412636ab3e67517d448be9eaab1b70c88eba9be22617b5d146257a11cc9b17" }, + "@cliffy/table@1.0.0-rc.7": { + "integrity": "9fdd9776eda28a0b397981c400eeb1aa36da2371b43eefe12e6ff555290e3180", + "dependencies": [ + "jsr:@std/fmt@~1.0.2" + ] + }, "@effigies/cliffy-command@1.0.0-dev.8": { "integrity": "d6489c66bf7f603225a426b26b62eaee32bf6da04b69056bcb015a1f17190087", "dependencies": [ "jsr:@cliffy/flags", "jsr:@cliffy/internal", + "jsr:@cliffy/table", "jsr:@effigies/cliffy-table@^1.0.0-dev.5", "jsr:@std/fmt@~1.0.2", "jsr:@std/text" @@ -242,8 +250,8 @@ "ieee754@1.2.1": { "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" }, - "ignore@6.0.2": { - "integrity": "sha512-InwqeHHN2XpumIkMvpl/DCJVrAHgCsG5+cn1XlnLWGwtZBm8QJfSusItfrwx81CTp5agNZqpKU2J/ccC5nGT4A==" + "ignore@7.0.3": { + "integrity": "sha512-bAH5jbK/F3T3Jls4I0SO1hmPR0dKU0a7+SY6n1yzRtG54FLO8d6w/nxLFX2Nb7dBu6cCWXPaAME6cYqFUMmuCA==" }, "inherits@2.0.3": { "integrity": "sha512-x00IRNXNy63jwGkJmzPigoySHbaqpNuzKbBOmzK+g2OdZpQ9w+sxCN+VSB3ja7IAge2OP2qpfxTjeNcyjmW1uw==" @@ -428,7 +436,7 @@ "npm:@bids/nifti-reader-js@0.6.9", "npm:ajv@8.17.1", "npm:hed-validator@3.15.5", - "npm:ignore@6.0.2" + "npm:ignore@7.0.3" ] } } diff --git a/docs/user_guide/command-line.md b/docs/user_guide/command-line.md index 47c93437b..c8db5d141 100644 --- a/docs/user_guide/command-line.md +++ b/docs/user_guide/command-line.md @@ -84,6 +84,8 @@ warnings, errors or ignored. } ``` +When a configuration specifies `location` without leading `/` it is interpreted +as a glob pattern following gitignore syntax. The issues are partial matches of the [Issues] that the validator accumulates. Pass the `--json` flag to see the issues in detail. diff --git a/src/files/ignore.ts b/src/files/ignore.ts index 3f362c081..36b3e2c09 100644 --- a/src/files/ignore.ts +++ b/src/files/ignore.ts @@ -31,7 +31,6 @@ export class FileIgnoreRules { config: string[], addDefaults: boolean = true, ) { - // @ts-expect-error this.#ignore = ignore() if (addDefaults) { this.#ignore.add(defaultIgnores) diff --git a/src/issues/datasetIssues.test.ts b/src/issues/datasetIssues.test.ts index 651cdbda4..a58b4c0ed 100644 --- a/src/issues/datasetIssues.test.ts +++ b/src/issues/datasetIssues.test.ts @@ -25,6 +25,16 @@ Deno.test('DatasetIssues management class', async (t) => { assertEquals(foundIssue[0].code, 'TEST_FILES_ERROR') }) + await t.step('get issues with glob pattern', () => { + const issues = new DatasetIssues() + issues.add({ code: 'TEST_FILES_ERROR', location: '/acq-mprage_T1w.json' }, 'Test issue') + issues.add({ code: 'TEST_FILES_ERROR', location: '/acq-memprage_T1w.json' }, 'Test issue') + issues.add({ code: 'TEST_FILES_ERROR', location: '/acq-mb1_bold.json' }, 'Test issue') + issues.add({ code: 'TEST_FILES_ERROR', location: '/acq-mb4_bold.json' }, 'Test issue') + const foundIssue = issues.get({ location: '*_bold.json' }) + assertEquals(foundIssue.length, 2) + }) + await t.step('test groupBy', () => { const issues = new DatasetIssues() issues.add({ code: 'NOT_INCLUDED', location: '/file_1' }) diff --git a/src/issues/datasetIssues.ts b/src/issues/datasetIssues.ts index 3bb52df71..1e806498e 100644 --- a/src/issues/datasetIssues.ts +++ b/src/issues/datasetIssues.ts @@ -1,3 +1,4 @@ +import { default as ignore } from '@ignore' import { nonSchemaIssues } from './list.ts' import type { Issue, IssueDefinition, IssueFile, Severity } from '../types/issues.ts' export type { Issue, IssueDefinition, IssueFile, Severity } @@ -41,7 +42,12 @@ export class DatasetIssues { if (!value) { continue } - found = found.filter((x) => x[key as keyof Issue] === value) + if (key === 'location' && typeof value === "string" && !value.startsWith('/')){ + const key_ignore = ignore().add(value as string) + found = found.filter((x) => x[key] && key_ignore.ignores(x[key].slice(1, x[key].length))) + } else { + found = found.filter((x) => x[key as keyof Issue] === value) + } } return found } diff --git a/src/validators/filenameIdentify.test.ts b/src/validators/filenameIdentify.test.ts index 78ca37ebc..387693f47 100644 --- a/src/validators/filenameIdentify.test.ts +++ b/src/validators/filenameIdentify.test.ts @@ -1,4 +1,5 @@ import { assertEquals } from '@std/assert' +import { SEPARATOR_PATTERN } from '@std/path' import { BIDSContext } from '../schema/context.ts' import { _findRuleMatches, datatypeFromDirectory, hasMatch } from './filenameIdentify.ts' import { BIDSFileDeno } from '../files/deno.ts' @@ -67,12 +68,8 @@ Deno.test('test hasMatch', async (t) => { await t.step('No match', async () => { const tmpFile = Deno.makeTempFileSync() - const parts = tmpFile.split('/') - const file = new BIDSFileDeno( - parts.slice(0, parts.length - 1).join('/'), - parts[parts.length - 1], - ignore, - ) + const [ dir, base ] = tmpFile.split(SEPARATOR_PATTERN) + const file = new BIDSFileDeno(dir, `/${base}`, ignore) const context = new BIDSContext(file) await hasMatch(schema, context)