Skip to content

Commit 17250e1

Browse files
committed
Merge remote-tracking branch 'upstream/main' into dev
2 parents ae2d222 + d296de3 commit 17250e1

File tree

14 files changed

+365
-33
lines changed

14 files changed

+365
-33
lines changed

.github/CONTRIBUTING.md

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,10 +161,101 @@ git push -u origin feat/short-desc
161161

162162
Open PR, set base branch to `dev`.
163163

164+
### Conventions for branches, commits and changelogs
165+
166+
The following conventions are intended to make contributions legible to other contributors
167+
and, ultimately, users.
168+
They are also there to help you, as a contributor, focus on doing one task at a time.
169+
170+
The following are common types of contributions, sorted roughly by order of interest
171+
to the reader:
172+
173+
| Contribution type | Branch prefix | Commit prefix | Changelog section |
174+
|-------------------|---------------|---------------|-------------------------|
175+
| Bug fix | `fix/` | `fix:` | Fixed |
176+
| Feature | `feat/` | `feat:` | Added |
177+
| Documentation | `doc/` | `doc:` | Added or Infrastructure |
178+
| Refactor | `rf/` | `rf:` | Changed |
179+
| Testing | `test/` | `test:` | Changed |
180+
| Style-only | `sty/` | `style:` | Infrastructure |
181+
| Maintenance | `chore/` | `chore:` | Infrastructure |
182+
183+
If you are contributing a bug-fix, it can help focus your efforts to name your branch
184+
`fix/problem-with-X`, and start commit messages where you write fixes with `fix:`.
185+
Similarly, branches and commits that focus on features, documentation, refactors,
186+
and so on, all have prefixes that help your reader understand what you were trying to do.
187+
188+
If you find your contribution spanning more than one of these sections,
189+
it might be worth breaking into multiple pull requests.
190+
Exceptions include tests and documentation relevant to the main thrust of the PR,
191+
which are always welcome.
192+
193+
None of this is set in stone, and we all make mistakes, so don't worry about
194+
following it to the letter.
195+
We will let you know if your contribution is doing too many things and work with
196+
you to split it into more manageable pieces.
197+
198+
#### Changelog entries
199+
200+
We are using the [scriv] changelog management tool to help keep our changelog organized.
201+
202+
Most pull requests will deserve changelog entries, and some may deserve more than one.
203+
Scriv allows changelog entries to be made as part of the pull request, which gives
204+
the contributor and the reviewer a chance to consider the impact of the pull request.
205+
206+
To add an entry, run:
207+
208+
```
209+
scriv create --edit
210+
```
211+
212+
(If you're wondering how to install `scriv`, we recommend using [uvx scriv][].)
213+
214+
Your editor will open a Markdown file with commented sections.
215+
Find the appropriate section(s) for your contribution and write a 1-3 line description.
216+
217+
#### Style contributions
218+
219+
Style changes in code can be a source of frustration.
220+
Some editors will reformat entire files when a single line is changed,
221+
swamping the meaningful change with a large number of cosmetic changes.
222+
223+
We have provided a [`.editorconfig`](https://editorconfig.org) file in the repository,
224+
which should be respected by [most editors](https://editorconfig.org/#pre-installed),
225+
and there are plugins available for [others](https://editorconfig.org/#download).
226+
Additionally, we use `deno fmt` to format the code in this repository.
227+
Using an autoformatter like this helps avoid (ongoing) disagreements over style preferences
228+
so we can focus on the content of the work.
229+
230+
Even with these, it is possible that when you go to commit your changes,
231+
you have changed more than you intended to.
232+
One reason this can happen is that we might have forgetten to autoformat our code.
233+
234+
One tool for this situation is `git add --patch` (or `-p`).
235+
This tool shows you each change in turn, allowing you to decide whether or not to
236+
"stage" the change. Stage only the chunks containing the pieces you meant to change,
237+
and commit those. You can then `git checkout .` to discard the remaining changes.
238+
239+
It is sometimes unavoidable to reformat large portions of code.
240+
In these cases, please make a style-only commit,
241+
followed by a commit with the meaningful changes.
242+
This will speed up review significantly.
243+
244+
Overall, a style-only pull request should be a rare event,
245+
typically when adopting or upgrading an autoformatter.
246+
This will generally have the effect of introducing merge conflicts,
247+
so we may refrain from doing it for a while.
248+
If you're feeling the urge, it's best to ask!
249+
250+
164251
[link_git]: https://git-scm.com/
165252
[link_handbook]: https://guides.github.com/introduction/git-handbook/
166253
[link_swc_intro]: http://swcarpentry.github.io/git-novice/
167254
[link_signupinstructions]: https://help.github.com/articles/signing-up-for-a-new-github-account
168255
[link_pullrequest]: https://help.github.com/articles/creating-a-pull-request-from-a-fork
169256
[link_fork]: https://help.github.com/articles/fork-a-repo/
170257
[link_clone]: https://help.github.com/articles/cloning-a-repository
258+
[conventional commits]: https://www.conventionalcommits.org/en/v1.0.0/
259+
[git blame]: https://docs.github.com/en/repositories/working-with-files/using-files/viewing-a-file#viewing-the-line-by-line-revision-history-for-a-file
260+
[scriv]: https://scriv.readthedocs.io/en/latest/
261+
[uvx]: https://docs.astral.sh/uv/guides/tools/

.github/workflows/web_build.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,13 @@ jobs:
6161
working-directory: dev/web
6262
- name: Nest dev inside stable
6363
run: mv dev/web/dist stable/web/dist/dev
64+
- name: Add legacy/ redirect
65+
run: |
66+
mkdir $DIR
67+
echo '<html><meta http-equiv="refresh" content="0; URL='$URL'"></html>' > $DIR/index.html
68+
env:
69+
DIR: stable/web/dist/legacy
70+
URL: https://bids-standard.github.io/legacy-validator/
6471
- name: Upload GitHub Pages artifact
6572
uses: actions/upload-pages-artifact@v3
6673
with:
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
-->
6+
7+
<!--
8+
### Removed
9+
10+
- A bullet item for the Removed category.
11+
12+
-->
13+
<!--
14+
### Added
15+
16+
- A bullet item for the Added category.
17+
18+
-->
19+
<!--
20+
### Changed
21+
22+
- A bullet item for the Changed category.
23+
24+
-->
25+
<!--
26+
### Deprecated
27+
28+
- A bullet item for the Deprecated category.
29+
30+
-->
31+
### Fixed
32+
33+
- Improve handling of `.bidsignore` files in the web validator.
34+
Ignores matching directories but not the files they contained could fail to match.
35+
(#113)
36+
37+
<!--
38+
### Security
39+
40+
- A bullet item for the Security category.
41+
42+
-->
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
-->
6+
7+
<!--
8+
### Added
9+
10+
- A bullet item for the Added category.
11+
12+
-->
13+
<!--
14+
### Changed
15+
16+
- A bullet item for the Changed category.
17+
18+
-->
19+
<!--
20+
### Fixed
21+
22+
- A bullet item for the Fixed category.
23+
24+
-->
25+
<!--
26+
### Deprecated
27+
28+
- A bullet item for the Deprecated category.
29+
30+
-->
31+
<!--
32+
### Removed
33+
34+
- A bullet item for the Removed category.
35+
36+
-->
37+
<!--
38+
### Security
39+
40+
- A bullet item for the Security category.
41+
42+
-->
43+
### Infrastructure
44+
45+
- Adopting [scriv](https://scriv.readthedocs.io/en/latest/) for changelog
46+
management.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<!--
2+
A new scriv changelog fragment.
3+
4+
Uncomment the section that is right (remove the HTML comment wrapper).
5+
-->
6+
7+
<!--
8+
### Added
9+
10+
- A bullet item for the Added category.
11+
12+
-->
13+
<!--
14+
### Changed
15+
16+
- A bullet item for the Changed category.
17+
18+
-->
19+
### Fixed
20+
21+
- Resolve issue with parsing headers of NIfTI files with large extensions.
22+
Fixes [issue 126].
23+
24+
[issue 126]: https://github.com/bids-standard/bids-validator/issues/126
25+
26+
<!--
27+
### Deprecated
28+
29+
- A bullet item for the Deprecated category.
30+
31+
-->
32+
<!--
33+
### Removed
34+
35+
- A bullet item for the Removed category.
36+
37+
-->
38+
<!--
39+
### Security
40+
41+
- A bullet item for the Security category.
42+
43+
-->
44+
<!--
45+
### Infrastructure
46+
47+
- A bullet item for the Infrastructure category.
48+
49+
-->

changelog.d/scriv.ini

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
[scriv]
2+
format = md
3+
main_branches = master, main, dev
4+
version = literal: deno.json: version
5+
categories = Added, Changed, Fixed, Deprecated, Removed, Security, Infrastructure

src/files/browser.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ export class BIDSFileBrowser implements BIDSFile {
5252
export async function fileListToTree(files: File[]): Promise<FileTree> {
5353
const ignore = new FileIgnoreRules([])
5454
const root = new FileTree('/', '/', undefined)
55-
const tree = filesToTree(files.map((f) => new BIDSFileBrowser(f, ignore, root)))
55+
const tree = filesToTree(files.map((f) => new BIDSFileBrowser(f, ignore, root)), ignore)
5656
const bidsignore = tree.get('.bidsignore')
5757
if (bidsignore) {
5858
try {

src/files/deno.ts

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -93,14 +93,17 @@ export class BIDSFileDeno implements BIDSFile {
9393

9494
/**
9595
* Read bytes in a range efficiently from a given file
96+
*
97+
* Reads up to size bytes, starting at offset.
98+
* If EOF is encountered, the resulting array may be smaller.
9699
*/
97100
async readBytes(size: number, offset = 0): Promise<Uint8Array> {
98101
const handle = this.#openHandle()
99102
const buf = new Uint8Array(size)
100103
await handle.seek(offset, Deno.SeekMode.Start)
101-
await handle.read(buf)
104+
const nbytes = await handle.read(buf) ?? 0
102105
handle.close()
103-
return buf
106+
return buf.subarray(0, nbytes)
104107
}
105108

106109
/**
@@ -151,17 +154,14 @@ async function _readFileTree(
151154
*/
152155
export async function readFileTree(rootPath: string): Promise<FileTree> {
153156
const ignore = new FileIgnoreRules([])
154-
try {
155-
const ignoreFile = new BIDSFileDeno(
156-
rootPath,
157-
'.bidsignore',
158-
ignore,
159-
)
160-
ignore.add(await readBidsIgnore(ignoreFile))
161-
} catch (err) {
162-
if (err && typeof err === 'object' && !('code' in err && err.code === 'ENOENT')) {
163-
logger.error(`Failed to read '.bidsignore' file with the following error:\n${err}`)
157+
const tree = await _readFileTree(rootPath, '/', ignore)
158+
const bidsignore = tree.get('.bidsignore')
159+
if (bidsignore) {
160+
try {
161+
ignore.add(await readBidsIgnore(bidsignore as BIDSFile))
162+
} catch (err) {
163+
console.log(`Failed to read '.bidsignore' file with the following error:\n${err}`)
164164
}
165165
}
166-
return _readFileTree(rootPath, '/', ignore)
166+
return tree
167167
}

src/files/filetree.test.ts

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { assert, assertEquals } from '@std/assert'
22
import type { FileIgnoreRules } from './ignore.ts'
3-
import type { FileTree } from '../types/filetree.ts'
3+
import type { BIDSFile, FileTree } from '../types/filetree.ts'
44
import { filesToTree, pathsToTree } from './filetree.ts'
55

66
Deno.test('FileTree generation', async (t) => {
@@ -50,4 +50,19 @@ Deno.test('FileTree generation', async (t) => {
5050
assert(tree.contains(['sub-01', 'anat']))
5151
assert(tree.contains(['sub-01', 'anat', 'sub-01_T1w.nii.gz']))
5252
})
53+
await t.step('converts a list with ignores', async () => {
54+
const tree = pathsToTree(
55+
['/dataset_description.json', '/README.md', '/.bidsignore', '/bad_file'],
56+
['bad_file'],
57+
)
58+
assertEquals(tree.directories, [])
59+
assertEquals(tree.files.map((f) => f.name), [
60+
'dataset_description.json',
61+
'README.md',
62+
'.bidsignore',
63+
'bad_file',
64+
])
65+
const bad_file = tree.get('bad_file') as BIDSFile
66+
assert(bad_file.ignored)
67+
})
5368
})

src/files/filetree.ts

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,29 @@
11
import { parse, SEPARATOR_PATTERN } from '@std/path'
22
import * as posix from '@std/path/posix'
33
import { type BIDSFile, FileTree } from '../types/filetree.ts'
4+
import { FileIgnoreRules } from './ignore.ts'
45

56
const nullFile = {
67
size: 0,
7-
ignored: false,
88
stream: new ReadableStream(),
99
text: () => Promise.resolve(''),
1010
readBytes: async (size: number, offset?: number) => new Uint8Array(),
1111
parent: new FileTree('', '/'),
1212
viewed: false,
1313
}
1414

15-
export function pathToFile(path: string): BIDSFile {
15+
export function pathToFile(path: string, ignored: boolean = false): BIDSFile {
1616
const name = path.split('/').pop() as string
17-
return { name, path, ...nullFile }
17+
return { name, path, ignored, ...nullFile }
1818
}
1919

20-
export function pathsToTree(paths: string[]): FileTree {
21-
return filesToTree(paths.map(pathToFile))
20+
export function pathsToTree(paths: string[], ignore?: string[]): FileTree {
21+
const ignoreRules = new FileIgnoreRules(ignore ?? [])
22+
return filesToTree(paths.map((path) => pathToFile(path, ignoreRules.test(path))))
2223
}
2324

24-
export function filesToTree(fileList: BIDSFile[]): FileTree {
25+
export function filesToTree(fileList: BIDSFile[], ignore?: FileIgnoreRules): FileTree {
26+
ignore = ignore ?? new FileIgnoreRules([])
2527
const tree: FileTree = new FileTree('/', '/')
2628
for (const file of fileList) {
2729
const parts = parse(file.path)
@@ -37,7 +39,7 @@ export function filesToTree(fileList: BIDSFile[]): FileTree {
3739
current = exists
3840
continue
3941
}
40-
const newTree = new FileTree(posix.join(current.path, level), level, current)
42+
const newTree = new FileTree(posix.join(current.path, level), level, current, ignore)
4143
current.directories.push(newTree)
4244
current = newTree
4345
}

0 commit comments

Comments
 (0)