Repository: bids-standard/pybids

Issue:
FYI: I enabled integration for pybids on zenodo
Ideally .zenodo.json (like nipype and now datalad has) should be in place as well


Discussion:
We should have a .zenodo.json before the release, IMO.

So I guess this is as good a place as any to raise the question of author ordering.
I'd ideally like to go first (though last would also be okay given some other ordering scheme). Ordering by either number of commits or LOC converges reasonably well with my sense of contributions thus far, except we should probably drop all the shablona-era commits from the repo before minting a DOI. I think there's basically nothing left from the original template. @effigies, would you mind rewriting history to squash/delete everything before, say, June 2016? I trust your git skills much more than my own.

@arokem, any objections to de-shablonafication?

I don't know if we should impose some cut-off on minimum contributions in terms of commits or LOC; I'm fine either way. Also not sure if there's anyone who's made valuable non-code contributions we should include; no one comes to mind right away. And I'm unclear on what the norm is for authorship in cases where code was borrowed from other repos (e.g., the HRF convolution taken from nistats—do we include @bthirion?). I'm fine going with whatever convention exists (though I'm guessing there isn't one).
No objections. Good luck with that rebase + force push!
LOL, we should absolutely not force push master. I can have a go at a script that ignores shablona commits, though.
Works for me!
Actually, it's probably much more expedient to just make a list of contributors to exclude (which can be revised in the event of new contributions).
```Shell
% git shortlog -nse d72caaf5933907ed699d57faddaec7bfc836ce6f..HEAD
   372  Tal Yarkoni <tyarkoni@gmail.com>
    90  adelavega <delavega@utexas.edu>
    71  Christopher J. Markiewicz <markiewicz@stanford.edu>
    59  Chris Gorgolewski <krzysztof.gorgolewski@gmail.com>
    47  Taylor Salo <tsalo006@fiu.edu>
    42  Chris Filo Gorgolewski <krzysztof.gorgolewski@gmail.com>
    31  Krista DeStasio <kdestasio@gmail.com>
    23  Yaroslav Halchenko <debian@onerussian.com>
    21  delavega4 <aleph4@gmail.com>
    20  Chris Markiewicz <effigies@gmail.com>
    19  Dmitry Petrov <to.dmitry.petrov@gmail.com>
    10  tyarkoni <tyarkoni@gmail.com>
     8  Kirstie Whitaker <kw401@cam.ac.uk>
     7  Elizabeth DuPre <emd222@cornell.edu>
     7  gkiar <gkiar07@gmail.com>
     5  Lee Tirrell <ltirrell@corticometrics.com>
     4  Alejandro de la Vega <aleph4@gmail.com>
     4  Chris Markiewicz <markiewicz@stanford.edu>
     4  Dylan <Dylan.Nielson@nih.gov>
     4  Mainak Jas <mainakjas@gmail.com>
     4  Michael Hanke <michael.hanke@gmail.com>
     3  Alexander <alexander.radievich@gmail.com>
     3  Dylan Nielson <adenosine@gmail.com>
     2  Alexander Ivanov <alexander.radievich@gmail.com>
     2  Oscar Esteban <code@oscaresteban.es>
     2  islast <islastaden@gmail.com>
     2  shotgunosine <adenosine@gmail.com>
     1  Adina Wagner <adina.wagner@t-online.de>
     1  Ariel Rokem <arokem@gmail.com>
     1  Chris Holdgraf <choldgraf@berkeley.edu>
     1  Johan Carlin <johan.carlin@gmail.com>
     1  Matteo Visconti dOC <matteo.visconti.gr@dartmouth.edu>
     1  Ross Blair <rosswilsonblair@gmail.com>
     1  bthirion <bertrand.thirion@inria.fr>
     1  oesteban <code@oscaresteban.es>
```

Add in a `.mailmap`, and we're most of the way done.
Looks good to me. I note that some people (Dylan, Alejandro, Alexander, Oscar) have contributions from multiple addresses, so they should probably be consolidated. I think that affects ordering for a couple of people. (EDIT: oh, I see, that's what a `.mailmap` does.)

Paging @adelavega @chrisfilo @tsalo @kdestasio @yarikoptic @hyperswitcher @KirstieJane @emdupre @gkiar @ltirrell @Shotgunosine @jasmainak @mih @oesteban @Islast @AdinaWagner @arokem @choldgraf @jooh @mvdoc @bthirion:

1) Are you okay being included in the pybids author list (we're minting a Zenodi DOI)?
2) Do you have any objection to an order roughly like the above?
3) Can you think of anyone who's contributed to pybids intellectually but isn't listed above?

Absence of response will be taken as acquiescence.
Great, thx ! --- take it as  a clever invitation to contribute more...
By lines:

```Python
% git-line-summary

 project  : pybids
 lines    : 88226
 authors  :
   67100 Chris Gorgolewski           76.1%
    6172 Tal Yarkoni                 7.0%
    5293 Mainak Jas                  6.0%
    2606 Christopher J. Markiewicz   3.0%
    1717 Taylor Salo                 1.9%
    1626 arokem                      1.8%
     695 adelavega                   0.8%
     656 Yaroslav Halchenko          0.7%
     624 islast                      0.7%
     502 bthirion                    0.6%
     355 shotgunosine                0.4%
     276 Dmitry Petrov               0.3%
     237 Krista DeStasio             0.3%
      73 Dylan                       0.1%
      64 delavega4                   0.1%
      50 Lee Tirrell                 0.1%
      35 Chris Markiewicz            0.0%
      34 Dylan Nielson               0.0%
      31 Elizabeth DuPre             0.0%
      17 gkiar                       0.0%
      14 Chris Filo Gorgolewski      0.0%
       8 Chris Holdgraf              0.0%
       7 Michael Hanke               0.0%
       7 Adina Wagner                0.0%
       6 tyarkoni                    0.0%
       6 Oscar Esteban               0.0%
       4 Andreas Mayer               0.0%
       4 Alexander                   0.0%
       3 oesteban                    0.0%
       3 Not Committed Yet           0.0%
       1 Johan Carlin                0.0%
```

I haven't figured out how to get this, ignoring lines that predate a certain commit, but it definitely boosts @bthirion's ranking.
Thanks @tyarkoni ! Looks good to me
Awesome, thx.

On Tue, Nov 27, 2018, 22:09 Mainak Jas <notifications@github.com wrote:

> Thanks @tyarkoni <https://github.com/tyarkoni> ! Looks good to me
>
> —
> You are receiving this because you were mentioned.
> Reply to this email directly, view it on GitHub
> <https://github.com/bids-standard/pybids/issues/299#issuecomment-442217815>,
> or mute the thread
> <https://github.com/notifications/unsubscribe-auth/AAIVH_sfOet67xiNjKpL3TDdrL4Afp_Xks5uzaoXgaJpZM4YzR5r>
> .
>

Uh, with all due respect to @chrisfilo and @jasmainak, my completely impartial judgment is that we should go with the commits version. ;)
I knew this was coming ;)
Looks good to me! The only modification I'd make is an asterisk by @tyarkoni's name noting that I receive co-authorship for each of his commits because I am his personal muse.
I'm ok with any order. Thanks for putting this together.
Sounds good to me! Wow I really need to get my git configs in order. 
cool, thx! :)
> By lines:
> 
> ```python
> % git-line-summary
> 
>  project  : pybids
>  lines    : 88226
>  authors  :
>    67100 Chris Gorgolewski           76.1%
>     6172 Tal Yarkoni                 7.0%
>     5293 Mainak Jas                  6.0%
> ....
> ```

whoohoo, I didn't know this command -- but now I will know how to play the game:
```shell
$> history
15363  git-sedi '$' ' '
15364  git commit -m 'Added trailing space everywhere I could' -a

$> git-line-summary                                 

 project  : pybids
 lines    : 88224
 authors  :
   87196 Yaroslav Halchenko       98.8%
     623 islast                   0.7%
     355 shotgunosine             0.4%
      25 Lee Tirrell              0.0%
      19 Tal Yarkoni              0.0%
       5 Chris Filo Gorgolewski   0.0%
       1 Krista DeStasio          0.0%

git-line-summary  21.80s user 8.24s system 107% cpu 27.873 total
```
crap... I am not the only one!!! ok - binary files and files without trailing newline in the last line, but what about this one?
```shell
(git)hopa:~/proj/bids/pybids[master]bids/layout/tests/data
$> git blame sample_validation_config.json | head
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  1) { 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  2)     "name": "user_sequences", 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  3)     "sequences": [ 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  4)         { 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  5)             "modality": "func", 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  6)             "session": "wave1", 
17386047 bids/grabbids/validation_config.json                 (Krista DeStasio    2018-08-10 02:34:50 -0700  7)             "type": "bold", 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  8)             "task": "sst", 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500  9)             "runs": 2 
e6958c9b bids/layout/tests/data/sample_validation_config.json (Yaroslav Halchenko 2018-11-27 18:41:40 -0500 10)         }, 
```
need to run, but will leave it as a puzzle for hungry minds ;)
I wish to amend our charter and propose that we exclude @yarikoptic from the author list
I ran out of "words"
I wish to amend our charter and propose that @yarikoptic have his emoji privileges revoked
Oh come on, make up your mind finally - one or another, chapter forbids multiple revocations if it isn't April 31st!!! 
Thank you for including me and Isla Staden (@Islast). 

If this is useful: Isla's ORCID is 0000-0002-0795-1154 and my ORCID is 0000-0001-8498-4059.
Thanks @KirstieJane! Was going to get around to asking for these at some point. I'll populate an initial `.zenodo.json` using any data I can grab off of other projects, and then people can submit corrections to the PR.

I'm thinking that number of commits in general is going to correlate with effort more than number of lines (with exceptions of chunks lifted wholesale from other projects -- sorry, Bertrand), so unless anyone objects, I'm going to follow `git shortlog -nse` for ordering.

Resolving patch:
diff --git a/tools/prep_zenodo.py b/tools/prep_zenodo.py
new file mode 100755
--- /dev/null
+++ b/tools/prep_zenodo.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python3
+import git
+import json
+from subprocess import run, PIPE, CalledProcessError
+from pathlib import Path
+from tempfile import TemporaryDirectory
+
+
+def decommify(name):
+    return ' '.join(name.split(', ')[::-1])
+
+
+# List of repositories whose commits should be counted as contributions
+codependents = ['https://github.com/grabbles/grabbit.git']
+
+# Last shablona commit
+origin_commit = 'd72caaf5933907ed699d57faddaec7bfc836ce6f'
+
+git_root = Path(git.Repo('.', search_parent_directories=True).working_dir)
+zenodo_file = git_root / '.zenodo.json'
+
+zenodo = json.loads(zenodo_file.read_text()) if zenodo_file.exists() else {}
+
+orig_creators = zenodo.get('creators', [])
+creator_map = {decommify(creator['name']): creator
+               for creator in orig_creators}
+
+shortlog = run(['git', 'shortlog', '-ns', f'{origin_commit}..'], stdout=PIPE)
+counts = [line.split('\t', 1)[::-1]
+          for line in shortlog.stdout.decode().split('\n') if line]
+
+# Get additional commit counts from dependencies
+with TemporaryDirectory() as tmpdir:
+    tmppath = Path(tmpdir)
+    for repo in codependents:
+        repo_dir = str(tmppath / repo.rsplit('/', 1)[1].split('.', 1)[0])
+        try:
+            clone = run(['git', 'clone', repo, repo_dir], check=True)
+        except CalledProcessError as err:
+            raise RuntimeError("Could not clone {}".format(repo)) from err
+        tag = run(['git', '-C', repo_dir, 'tag'], stdout=PIPE)
+        latest_tag = tag.stdout.decode().strip().rsplit('\n', 1)[1]
+        dep_shortlog = run(
+            ['git', '-C', repo_dir, 'shortlog', '-ns', latest_tag],
+            stdout=PIPE)
+        counts.extend(line.split('\t', 1)[::-1]
+                      for line in dep_shortlog.stdout.decode().split('\n')
+                      if line)
+
+commit_counts = {}
+for committer, commits in counts:
+    commit_counts[committer] = commit_counts.get(committer, 0) + int(commits)
+
+# Stable sort:
+# Number of commits in reverse order
+# Ties broken by alphabetical order of first name
+committers = [committer
+              for committer, _ in sorted(commit_counts.items(),
+                                         key=lambda x: (-x[1], x[0]))]
+
+# Tal to the top
+first_author = 'Tal Yarkoni'
+if committers[0] != first_author:
+    committers.remove(first_author)
+    committers.insert(0, first_author)
+
+creators = [
+    creator_map.get(committer, {'name': committer})
+    for committer in committers
+    ]
+
+zenodo['creators'] = creators
+zenodo_file.write_text(json.dumps(zenodo, indent=2, sort_keys=True) + '\n')


Test patch: