Skip to content

Standards

Daniel A Kessler edited this page May 25, 2016 · 31 revisions

Hi everybody!

I'm hoping this page can document directly, or have links to pages, with documentation regarding coding standards that we all use.

Documentation Conventions

  • mcRoot is the stand-in for the top-level of the git work tree. For example, my git repository may live at ~/repos/ MethodsCore, but Mike's might be at ~/gitstuff/Mike/MethodsCore. Throughout documentation (and even in some functions) we use mcRoot to refer to this path.

Matlab Conventions

Function Naming

Similar to how SPM does it, custom functions that we write that we anticipate being shared across packages should start with mc_. For example, mc_GenPath.m is used by a variety of our "central" scripts.

This scripts will live in mcRoot/matlabScripts/ and many of our functions will add this path.

Git Conventions

Repositories

There is one major repository, called universe throughout, though your alias for it may vary.

This repository is policed by group policy and review.

Each developer will also have his or her own repository. It is expected that users may freely fetch from this repository, but for the most part only the owner will ever push or write to it.

Workflow

Per discussion in #386, we are shifting to the popular git branching workflow. Unreleased toolboxes will continue to live in "name_beta" branches. Released toolboxes will be folded into the mainline of work.

For details, see the blog post detailed the git branching workflow model. In brief, here are the key branches

  • public: corresponds to currently released code
  • dev: corresponds to development version, branches off of public
  • release: periodically branches off of dev to consolidate release work. Merges into public
  • features: names vary depending on feature. Branches off of dev, merges into dev

Unique to us

  • Utilities_base: contains base version of all contributed Utilities (e.g. SPM, FastICA). Merges into dev prior to release
  • Utilities_patched: contains our tweaks to contributed Utilities. Pulls in Utilities_base when it gets updated
  • Toolbox_beta

Contributed Utilities

A good deal of our code depends on (typically publicly available) code written by other developers (e.g. marsbar, BrainNetView). We occasionally add our own hacks on top of this. And then the developers release a new version, and we have to reconcile our changes on version 1 with their improvements. As such, we'll track updates to these utilities in a branch called "Utilities_base" and our hacks on top in "Utilities_patched." This way, if a new version of a tool comes out, we simply update base, then pull it into patched to try applying our tweaks on top of it.

Tags

releaseX.Y These will be tags on the public branch to indicate the current release number. They will follow the format X.Ya, so for example our current release is 1.5, and we just completed a hotfix so the hotfix release gets tagged 1.5a.

Going away

  • Branches for released toolboxes. These will be folded into public, then into dev
  • Branches for individual toolboxes. All base versions will fold into a single base, all patched into a single patched
  • Core branch. This will be folded into Utilities_base (b/c it includes SPM). Changes to checkout hooks in future will be treated as regular feature branches off of dev

Branch/Merge Workflow

Overall Scheme

Git Workflow

The above image depicts how information will flow. NOTE: master in figure = public in our repo

If beginning work on a new feature in a released toolbox, simply branch off of dev. When done, submit a pull request back into dev.

If working on an unreleased feature, branch off of its beta channel, and merge back into its beta channel.

When preparing for a release, create a release branch based on dev to allow development to continue on dev while final testing and fixes occurs in release. Once it's ready, pull it into public

Preparing for Release

When a release is approaching, we will need to gather together released feature beta branches.

Let's imagine that we are preparing to release version 2.3, and it will include several new features from svmbatch and som toolboxes.

  1. Update local repository from universe git fetch universe
  2. Base a new release branch off the dev branch git checkout universe/dev -b release/2.3
  3. Perform rigorous testing.
  4. Make any changes necessary to pass testing git commit -am "fixed bugs"
  5. Update any tags (e.g. mc_release_tag, others)
  6. Update the root level README to discuss the current release.
  7. Push your changes to your repository git push github/dankessler release/2.3
  8. Submit pull request to merge your release branch into public. Your base branch will be UMPsychMethodsCore@public while your head branch will be dankessler@release/2.3
  9. You should probably get a +1 from the rest of the development team, who will be broken down into testing teams, and official approval will probably come from a unanimous vote at a MethodsCore meeting or something like that.
  10. Make any necessary commits to address testing issues, and repeat testing to ensure that they actually address problems.
  11. Update your pull request with these changes by re-pushing your updated branch git push github/dankessler release/2.3
  12. Accept the pull request.
  13. Update your repository again git fetch universe
  14. Tag the new release in the public branch git tag -a Release_2.3 universe/public. In the editor, write the release number and some description of the release.
  15. Push your tag to the remote git push universe tag Release_2.3
  16. Pull public into dev to incorporate any fixes that were added during release prep

Hotfixes

From time to time, something may slip out that is broken. We'll follow an actual example that recently occurred.

fileparts.m used to give four output arguments [a b c d] = fileparts(path). Now it gives just three. Attempts to assign to four output arguments will result in an error. Unfortunately, some of our code uses this now disallowed usage, and even worse, some of the SPM toolboxes use this pattern. @mangstad and I talked about the problem and decided the best approach was to provide a fileparts.m function of our own in the matlabScripts toolbox that would take precedence. This would have all the bells & whistles of the newest fileparts.m in 2012b, but would provide an optional fourth argument as an empty string.

The approach for a hotfix is similar to what would've happened if the bug had been detected at the release testing stage. We will branch off of public, make our fix, test to ensure that this fixes the problem, and then pull that into public. We'll also update our tag after that pull, and run the self update scripts on any deployments.

Steps

  1. Update your local repository from universe git fetch universe
  2. Base a new branch off of public git checkout universe/public -b fix/filepartsBUG
  3. Do work in this branch git commit -am "fixed the bug, yay"
  4. Perform some serious testing to ensure that this fixes the problem and doesn't make any new ones.
  5. Push your feature branch to your repository git push github/dankessler fix/filepartsBUG
  6. Submit pull request to merge your hotfix branch into public using github.
  7. Write up a justification, ideally referencing the pending issue that identified the bug. You should probably ping the rest of the development team here.
  8. After testing, accept the pull request.
  9. Update your local repository. git fetch universe
  10. Tag the new release in the public branch git tag -a Release_1.1a universe/public. In the editor, write the release number and a description of the bug fix.
  11. Push your tag to the remote git push universe tag Release_1.1a
  12. Email the Methods Core team. The maintainer of each deployment will need to run the self_update.sh script located in mcRoot/.deploy/src in order to get the updated version.
  13. Pull the newly updated public into dev