Contributing Guide#
Welcome to the contributing guide!
This guide exists to help BIDS users to contribute to the BIDS validator with their own code. We cover:
Knowledge that might be helpful to have (or acquire)
How to set up your development environment for BIDS validator
Ways to contribute code to BIDS validator (e.g., for a BIDS extension proposal)
If you find that something is unclear, please open an issue so that we can improve this guide.
Knowledge that will help you along the way#
Git#
We use git for source control.
If you’re not yet familiar with git, there are lots of great resources to help you
get started!
Some of our favorites include the git Handbook and
the Software Carpentry introduction to git.
In particular, you will want to become conversant with the following operations:
You should also configure configure git for your user, so your commits are properly attributed.
GitHub#
We use GitHub to manage contributions and have development discussions in the open. To participate, be sure you know how to
Coding knowledge#
Familiarize yourself with the command line on your system (e.g.,
bash)Basic knowledge about coding is helpful and familiarity with JavaScript is a big bonus, but you can contribute to the BIDS validator also without specific knowledge of JavaScript
Some knowledge about software testing (why we are doing it) would be nice
Using the development version of BIDS validator#
Install the required software:
In the GitHub interface, make a fork of https://github.com/bids-standard/bids-validator to your own user (called
USERfor the sake of the example)you will now have your own copy of BIDS validator at https://github.com/USER/bids-validator
Open a command line and navigate to the location on your computer from where you want to develop BIDS validator and clone your fork of the repository
You will now have a new directory called
bids-validatornavigate to that directory and run
git statusto verify that it’s agitdirectory
Install
bids-validatorwith:deno install -Agf --reload ./bids-validator/src/bids-validator.tsDeno will install the file to its
bindirectory. On Unix systems, this should be$HOME/.deno/bin. You may need to add this to yourPATH.
Now your development version of BIDS validator is set up and you can use it.
Whenever you checkout a new branch in your git repository, the
bids-validator executable is now pointing to that branch, and all changes in
that branch will be reflected in the behavior of bids-validator.
Before you start making changes, there are some more important points to consider:
We need to tell your git directory, that it has a remote counterpart (namely, the original BIDS validator). When that counterpart gets updated, you have to update your BIDS validator as well, to keep in sync.
run
git remote add upstream https://github.com/bids-standard/bids-validatorthen run
git remote -v, and it should show four entries: two of typeorigin, and two of typeupstreamoriginrefers to your fork of BIDS validator on GitHub, whereasupstreamrefers to the original BIDS validator repository on GitHubyou can use
upstreamto always stay up to date with changes that are being made on the original BIDS validator. For that, simply navigate to themainbranch of your repository usinggit checkout main, and then rungit pull upstream main
When you get completely stuck with your repository and you just want to reset it to be an exact mirror of the original BIDS validator, you can run the following command (Note: this will discard all current changes):
first checkout your main:
git checkout mainthen run:
git reset --hard upstream/main
Developing for the validator#
When proposing a feature or bug fix, you must decide which branch you will target:
main or dev.
In most cases you will want main, but read below to understand the purposes of
the two branches.
Branching policy#
The BIDS Validator’s main branch tracks the most recent release version of the specification:
https://bids-specification.readthedocs.io/en/stable/.
Pull requests made against the main branch should implement features or fix bugs in a way
that preserves consistency with the stable specification.
The dev branch is for features that are not yet in the released version of the BIDS
specification.
The purpose of this branch is to verify that proposed rules can be validated and
provide users with preview access to upcoming changes to the validator, increasing the chances
of catching issues with the specification or the validator, prior to release.
Changes to the dev branch may be reverted at any time.
How to prepare a pull request for your target branch#
If you’re going to target main, then start as follows:
git fetch upstream
git switch -c feat/short-desc upstream/main
This will create a new branch named feat/short-desc
(use fix/... for bug-fix branches, doc/... for documentation, etc.) starting
from the current state of the main branch on the upstream remote.
Instead of short-desc, use a few words to make the content of your branch
easily identifiable.
Once you have changes committed and ready for review you can run:
git push -u origin feat/short-desc
GitHub will then give you a link such as: https://github.com/bids-standard/bids-validator/compare/master…username:bids-validator:feat/short-desc?expand=1. Follow that link to create a pull request.
While you are creating the pull request, verify that the base branch is set to main.
For dev, the process is identical:
git fetch upstream
git switch -c feat/short-desc upstream/dev
# Add your feature
git push -u origin feat/short-desc
Open PR, set base branch to dev.
What to include in a pull request#
Test-driven development#
If you are fixing a bug, or adding a feature, it is strongly recommended to follow this pattern:
Verify that tests pass:
deno test -A srcWrite a test that fails (again, verify) because it reproduces your bug or exercises the feature that does not yet exist. This is a code-based specification of the behavior change.
Commit the test before doing any further development.
Fix the bug or implement the feature, and verify that tests now pass.
Some rules to keep you honest:
You can use several commits to implement your changes, but at the end, tests must pass.
Changes to the tests must be in their own commits and the commit message should explain why the specification has changed.
By developing in this way, you ensure that the feature works as expected, and that there will be a problem if somebody else breaks the contract you wrote.
Documentation#
As code changes, there is always a threat that documentation will no longer accurately describe the software. It is important to read the documentation to see whether the behavior you’re changing is documented. If so, it needs to be updated. If not, consider whether you wish it already had been, and be the change you want to see in the world!
Seriously, documentation is extremely important, and we know we don’t do it enough. Contributions that are only documentation are very much appreciated.
API#
We provide a programmatic API for downstream tools to build on the validator.
The API lives in src/api/, and exports components that.
If you’re writing a new class, interface, type or function, consider whether it will be useful for downstream developers to have access.
If you’re tempted to create a /tools or /util submodule,
it probably does not need to be in the API.
If you really think it’s important, let’s talk.
Conventions for branches, commits and changelogs#
The following conventions are intended to make contributions legible to other contributors and, ultimately, users. They are also there to help you, as a contributor, focus on doing one task at a time.
The following are common types of contributions, sorted roughly by order of interest to the reader:
Contribution type |
Branch prefix |
Commit prefix |
Changelog section |
|---|---|---|---|
Bug fix |
|
|
Fixed |
Feature |
|
|
Added |
Documentation |
|
|
Added or Infrastructure |
Refactor |
|
|
Changed |
Testing |
|
|
Changed |
Style-only |
|
|
Infrastructure |
Maintenance |
|
|
Infrastructure |
If you are contributing a bug-fix, it can help focus your efforts to name your branch
fix/problem-with-X, and start commit messages where you write fixes with fix:.
Similarly, branches and commits that focus on features, documentation, refactors,
and so on, all have prefixes that help your reader understand what you were trying to do.
If you find your contribution spanning more than one of these sections, it might be worth breaking into multiple pull requests. Exceptions include tests and documentation relevant to the main thrust of the PR, which are always welcome.
None of this is set in stone, and we all make mistakes, so don’t worry about following it to the letter. We will let you know if your contribution is doing too many things and work with you to split it into more manageable pieces.
Changelog entries#
We are using the scriv changelog management tool to help keep our changelog organized.
Most pull requests will deserve changelog entries, and some may deserve more than one. Scriv allows changelog entries to be made as part of the pull request, which gives the contributor and the reviewer a chance to consider the impact of the pull request.
To add an entry, run:
scriv create --edit
(If you’re wondering how to install scriv, we recommend using uvx scriv.)
Your editor will open a Markdown file with commented sections. Find the appropriate section(s) for your contribution and write a 1-3 line description.
Style contributions#
Style changes in code can be a source of frustration. Some editors will reformat entire files when a single line is changed, swamping the meaningful change with a large number of cosmetic changes.
We have provided a .editorconfig file in the repository,
which should be respected by most editors,
and there are plugins available for others.
Additionally, we use deno fmt to format the code in this repository.
Using an autoformatter like this helps avoid (ongoing) disagreements over style preferences
so we can focus on the content of the work.
Even with these, it is possible that when you go to commit your changes, you have changed more than you intended to. One reason this can happen is that we might have forgotten to autoformat our code.
One tool for this situation is git add --patch (or -p).
This tool shows you each change in turn, allowing you to decide whether or not to
“stage” the change. Stage only the chunks containing the pieces you meant to change,
and commit those. You can then git checkout . to discard the remaining changes.
It is sometimes unavoidable to reformat large portions of code. In these cases, please make a style-only commit, followed by a commit with the meaningful changes. This will speed up review significantly.
Overall, a style-only pull request should be a rare event, typically when adopting or upgrading an autoformatter. This will generally have the effect of introducing merge conflicts, so we may refrain from doing it for a while. If you’re feeling the urge, it’s best to ask!
Checking your work#
We use various tools to help us keep the repository in good shape.
We already mentioned deno fmt.
Additionally, we use:
deno lint- A tool that identifies potential bugs or maintenance debtdeno check- Run type checks without running the full test suitedeno publish --dry-run --allow-dirty- Test the repository for release readiness
It’s also a good idea to make sure that the docs build, if you’re updating them:
uv sync --locked --group=doc
uv run make -C docs clean html