Skip to content

Commit

Permalink
Merge pull request bids-standard#2116 from rwblair/feat/citationcff
Browse files Browse the repository at this point in the history
feat: Validate CITATION.cff
  • Loading branch information
effigies authored Aug 30, 2024
2 parents e0ada04 + 0c1b20a commit 690a34a
Show file tree
Hide file tree
Showing 9 changed files with 129 additions and 15 deletions.
4 changes: 2 additions & 2 deletions bids-validator/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ const flags = parse(Deno.args, {

const version = await getVersion()

let versionPlugin = {
const versionPlugin = {
name: 'version',
setup(build: esbuild.PluginBuild) {
build.onResolve({ filter: /\.git-meta\.json/ }, (args) => ({
Expand All @@ -46,7 +46,7 @@ const result = await esbuild.build({
format: 'esm',
entryPoints: [MAIN_ENTRY, CLI_ENTRY],
bundle: true,
outdir: path.join('dist','validator'),
outdir: path.join('dist', 'validator'),
minify: flags.minify,
target: ['chrome109', 'firefox109', 'safari16'],
plugins: [
Expand Down
17 changes: 9 additions & 8 deletions bids-validator/deno.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,20 +27,21 @@
]
},
"imports": {
"@ajv": "npm:ajv@8.16.0",
"@bids/schema": "jsr:@bids/schema@0.11.2-dev.2+7f1f6737",
"@cliffy/command": "jsr:@cliffy/command@1.0.0-rc.5",
"@cliffy/table": "jsr:@cliffy/table@1.0.0-rc.5",
"@hed/validator": "npm:hed-validator@3.15.4",
"@ignore": "npm:ignore@5.3.2",
"@libs/xml": "jsr:@libs/xml@5.4.13",
"@mango/nifti": "npm:nifti-reader-js@0.6.8",
"@std/assert": "jsr:@std/assert@1.0.2",
"@std/fmt": "jsr:@std/fmt@1.0.0",
"@std/fs": "jsr:@std/fs@1.0.1",
"@std/io": "jsr:@std/io@0.224.4",
"@std/log": "jsr:@std/log@0.224.5",
"@std/path": "jsr:@std/path@1.0.2",
"@ajv": "npm:ajv@8.16.0",
"@bids/schema": "jsr:@bids/schema@0.11.1-dev.4+a73c1b06",
"@cliffy/table": "jsr:@cliffy/table@1.0.0-rc.5",
"@cliffy/command": "jsr:@cliffy/command@1.0.0-rc.5",
"@hed/validator": "npm:hed-validator@3.15.4",
"@ignore": "npm:ignore@5.3.2",
"@mango/nifti": "npm:nifti-reader-js@0.6.8",
"@libs/xml": "jsr:@libs/xml@5.4.13"
"@std/yaml": "jsr:@std/yaml@^1.0.4"
},
"tasks": {
"test": "deno test -A src/tests/"
Expand Down
18 changes: 14 additions & 4 deletions bids-validator/src/issues/list.ts
Original file line number Diff line number Diff line change
Expand Up @@ -162,6 +162,20 @@ export const bidsIssues: IssueDefinitionRecord = {
severity: 'error',
reason: 'A json sidecar file was found without a corresponding data file',
},
BLACKLISTED_MODALITY: {
severity: 'error',
reason: 'The modality in this file is blacklisted through validator configuration.',
},
CITATION_CFF_VALIDATION_ERROR: {
severity: 'error',
reason:
"The file does not pass validation using the citation.cff standard's schema." +
'https://github.com/citation-file-format/citation-file-format/blob/main/schema-guide.md'
},
FILE_READ: {
severity: 'error',
reason: 'We were unable to read this file.'
}
}

const hedIssues: IssueDefinitionRecord = {
Expand Down Expand Up @@ -191,10 +205,6 @@ const hedIssues: IssueDefinitionRecord = {
reason:
"You should define 'HEDVersion' for this file. If you don't provide this information, the HED validation will use the latest version available.",
},
BLACKLISTED_MODALITY: {
severity: 'error',
reason: 'The modality in this file is blacklisted through validator configuration.',
},
}

export const hedOldToNewLookup: Record<number, Partial<keyof IssueDefinitionRecord>> = {
Expand Down
2 changes: 1 addition & 1 deletion bids-validator/src/setup/loadSchema.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { assert, assertObjectMatch } from '@std/assert'
import { loadSchema } from './loadSchema.ts'

Deno.test('schema yaml loader', async (t) => {
Deno.test('schema loader', async (t) => {
await t.step('reads in top level files document', async () => {
const schemaDefs = await loadSchema()
// Look for some stable fields in top level files
Expand Down
2 changes: 2 additions & 0 deletions bids-validator/src/validators/bids.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { sidecarWithoutDatafile, unusedStimulus } from './internal/unusedFile.ts
import { type BIDSContext, BIDSContextDataset } from '../schema/context.ts'
import type { parseOptions } from '../setup/options.ts'
import { hedValidate } from './hed.ts'
import { citationValidate } from './citation.ts'

/**
* Ordering of checks to apply
Expand All @@ -32,6 +33,7 @@ const perContextChecks: ContextCheckFunction[] = [
const perDSChecks: DSCheckFunction[] = [
unusedStimulus,
sidecarWithoutDatafile,
citationValidate,
]

/**
Expand Down
27 changes: 27 additions & 0 deletions bids-validator/src/validators/citation.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
import { assert } from '@std/assert'
import { pathsToTree } from '../files/filetree.ts'
import { BIDSFileDeno } from '../files/deno.ts'
import { citationValidate } from './citation.ts'
import { BIDSContextDataset } from '../schema/context.ts'
import { GenericSchema } from '../types/schema.ts'
import { loadSchema } from '../setup/loadSchema.ts'

Deno.test('citation validation', async (t) => {
const schema = await loadSchema()
await t.step('no errors on the good citation.cff', async () => {
const tree = pathsToTree(['CITATION.cff'])
const dsContext = new BIDSContextDataset({ tree })
const file = new BIDSFileDeno('tests/data/citation', 'good.cff')
tree.files[0].text = () => file.text()
await citationValidate({} as GenericSchema, dsContext)
assert(dsContext.issues.size === 0)
})
await t.step('An error on the bad citation.cff', async () => {
const tree = pathsToTree(['CITATION.cff'])
const dsContext = new BIDSContextDataset({ tree })
const file = new BIDSFileDeno('tests/data/citation', 'bad.cff')
tree.files[0].text = () => file.text()
await citationValidate({} as GenericSchema, dsContext)
assert(dsContext.issues.get({ code: 'CITATION_CFF_VALIDATION_ERROR' }).length === 1)
})
})
39 changes: 39 additions & 0 deletions bids-validator/src/validators/citation.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import type { GenericSchema } from '../types/schema.ts'
import type { BIDSFile, FileTree } from '../types/filetree.ts'
import type { BIDSContextDataset } from '../schema/context.ts'
import { schema as citationSchema } from '@bids/schema/citation'
import { compile } from './json.ts'
import type { DefinedError } from '@ajv'
import { parse } from '@std/yaml'

const citationFilename = 'CITATION.cff'

export async function citationValidate(
schema: GenericSchema,
dsContext: BIDSContextDataset,
) {
const citationFile = dsContext.tree.get(citationFilename)
if (!citationFile || 'directories' in citationFile) return
let citation: unknown = {}
try {
citation = parse(await citationFile.text())
} catch (error) {
dsContext.issues.add({
code: 'FILE_READ',
issueMessage: `Error from attempted read of file:\n${error}`,
location: citationFilename,
})
return
}
const validate = compile(citationSchema)
if (!validate(citation)) {
for (const err of validate.errors as DefinedError[]) {
dsContext.issues.add({
code: 'CITATION_CFF_VALIDATION_ERROR',
subCode: err['instancePath'],
issueMessage: err['message'],
location: citationFilename,
})
}
}
}
15 changes: 15 additions & 0 deletions bids-validator/tests/data/citation/bad.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
cff-version: 1.2.0
message: If you use this software, please cite it using these metadata.
title: My Research Software
abstract: This is my awesome research software. It does many things.
version: 0.11.2
date-released: "2021-07-18"
identifiers:
- description: This is the collection of archived snapshots of all versions of My Research Software
type: doi
value: "10.5281/zenodo.123456"
- description: This is the archived snapshot of version 0.11.2 of My Research Software
type: doi
value: "10.5281/zenodo.123457"
license: Apache-2.0
repository-code: "https://github.com/citation-file-format/my-research-software"
20 changes: 20 additions & 0 deletions bids-validator/tests/data/citation/good.cff
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
cff-version: 1.2.0
message: If you use this software, please cite it using these metadata.
title: My Research Software
abstract: This is my awesome research software. It does many things.
authors:
- family-names: Druskat
given-names: Stephan
orcid: "https://orcid.org/1234-5678-9101-1121"
- name: "The Research Software project"
version: 0.11.2
date-released: "2021-07-18"
identifiers:
- description: This is the collection of archived snapshots of all versions of My Research Software
type: doi
value: "10.5281/zenodo.123456"
- description: This is the archived snapshot of version 0.11.2 of My Research Software
type: doi
value: "10.5281/zenodo.123457"
license: Apache-2.0
repository-code: "https://github.com/citation-file-format/my-research-software"

0 comments on commit 690a34a

Please sign in to comment.