etc: teams: Add scope support.
Add a scope list to each team. This list defines all the files and directories that are mentored by the team. Also add a cc-members command that takes two Git revision strings as input, add returns the members that should be CC'ed given the files impacted between the two revisions. * etc/teams.scm.in (<team>)[scope]: New field. (team, list-teams): Adapt those procedures. (find-team-by-scope, diff-revisions): New procedures. (main): Add a "cc-members" command. * doc/contributing.texi ("Teams"): Document it. ("Sending a Patch Series"): Adapt it.master
parent
2784fcf14d
commit
2a66304535
|
@ -1406,6 +1406,47 @@ for more information. You can install @command{git send-email} with
|
||||||
@command{guix install git:send-email}.
|
@command{guix install git:send-email}.
|
||||||
@c Debbugs bug: https://debbugs.gnu.org/db/15/15361.html
|
@c Debbugs bug: https://debbugs.gnu.org/db/15/15361.html
|
||||||
|
|
||||||
|
To maximize the chances that you patch series is reviewed, the preferred
|
||||||
|
submission way is to use the @code{etc/teams.scm} script to notify the
|
||||||
|
appropriate team members (@pxref{Teams}).
|
||||||
|
|
||||||
|
@unnumberedsubsec Teams
|
||||||
|
@anchor{Teams}
|
||||||
|
@cindex teams
|
||||||
|
|
||||||
|
There are several teams mentoring different parts of the Guix source
|
||||||
|
code. To list all those teams, you can run from a Guix checkout:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ ./etc/teams.scm list-teams
|
||||||
|
id: mentors
|
||||||
|
name: Mentors
|
||||||
|
description: A group of mentors who chaperone contributions by newcomers.
|
||||||
|
members:
|
||||||
|
+ Christopher Baines <mail@@cbaines.net>
|
||||||
|
+ Ricardo Wurmus <rekado@@elephly.net>
|
||||||
|
+ Mathieu Othacehe <othacehe@@gnu.org>
|
||||||
|
+ jgart <jgart@@dismail.de>
|
||||||
|
+ Ludovic Courtès <ludo@@gnu.org>
|
||||||
|
@dots{}
|
||||||
|
@end example
|
||||||
|
|
||||||
|
You can run the following command to have the @code{Mentors} team put in
|
||||||
|
CC of a patch series:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ git send-email --to XXX@@debbugs.gnu.org $(./etc/teams.scm cc mentors) *.patch
|
||||||
|
@end example
|
||||||
|
|
||||||
|
The appropriate team or teams can also be inferred from the modified
|
||||||
|
files. For instance, if you want to send the two latest commits of the
|
||||||
|
current Git repository to review, you can run:
|
||||||
|
|
||||||
|
@example
|
||||||
|
$ guix shell -D guix
|
||||||
|
[env]$ git send-email --to XXX@@debbugs.gnu.org $(./etc/teams.scm cc-members HEAD~2 HEAD) *.patch
|
||||||
|
@end example
|
||||||
|
|
||||||
@node Tracking Bugs and Patches
|
@node Tracking Bugs and Patches
|
||||||
@section Tracking Bugs and Patches
|
@section Tracking Bugs and Patches
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
;;; GNU Guix --- Functional package management for GNU
|
;;; GNU Guix --- Functional package management for GNU
|
||||||
;;; Copyright © 2022 Ricardo Wurmus <rekado@elephly.net>
|
;;; Copyright © 2022 Ricardo Wurmus <rekado@elephly.net>
|
||||||
|
;;; Copyright © 2022 Mathieu Othacehe <othacehe@gnu.org>
|
||||||
;;;
|
;;;
|
||||||
;;; This file is part of GNU Guix.
|
;;; This file is part of GNU Guix.
|
||||||
;;;
|
;;;
|
||||||
|
@ -22,23 +23,27 @@
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; This code defines development teams and team members.
|
;; This code defines development teams and team members, as well as their
|
||||||
|
;; scope.
|
||||||
|
|
||||||
;;; Code:
|
;;; Code:
|
||||||
|
|
||||||
(use-modules (srfi srfi-1)
|
(use-modules (srfi srfi-1)
|
||||||
(srfi srfi-9)
|
(srfi srfi-9)
|
||||||
|
(srfi srfi-26)
|
||||||
(ice-9 format)
|
(ice-9 format)
|
||||||
(ice-9 match)
|
(ice-9 match)
|
||||||
(guix ui))
|
(guix ui)
|
||||||
|
(git))
|
||||||
|
|
||||||
(define-record-type <team>
|
(define-record-type <team>
|
||||||
(make-team id name description members)
|
(make-team id name description members scope)
|
||||||
team?
|
team?
|
||||||
(id team-id)
|
(id team-id)
|
||||||
(name team-name)
|
(name team-name)
|
||||||
(description team-description)
|
(description team-description)
|
||||||
(members team-members set-team-members!))
|
(members team-members set-team-members!)
|
||||||
|
(scope team-scope))
|
||||||
|
|
||||||
(define-record-type <person>
|
(define-record-type <person>
|
||||||
(make-person name email)
|
(make-person name email)
|
||||||
|
@ -49,11 +54,13 @@
|
||||||
(define* (person name #:optional email)
|
(define* (person name #:optional email)
|
||||||
(make-person name email))
|
(make-person name email))
|
||||||
|
|
||||||
(define* (team id #:key name description (members '()))
|
(define* (team id #:key name description (members '())
|
||||||
|
(scope '()))
|
||||||
(make-team id
|
(make-team id
|
||||||
(or name (symbol->string id))
|
(or name (symbol->string id))
|
||||||
description
|
description
|
||||||
members))
|
members
|
||||||
|
scope))
|
||||||
|
|
||||||
(define %teams
|
(define %teams
|
||||||
(make-hash-table))
|
(make-hash-table))
|
||||||
|
@ -276,6 +283,22 @@ importer."))
|
||||||
(error (format #false
|
(error (format #false
|
||||||
"no such team: ~a~%" name))))
|
"no such team: ~a~%" name))))
|
||||||
|
|
||||||
|
(define (find-team-by-scope files)
|
||||||
|
"Return the team(s) which scope matches at least one of the FILES, as list
|
||||||
|
of file names as string."
|
||||||
|
(hash-fold
|
||||||
|
(lambda (key team acc)
|
||||||
|
(if (any (lambda (file)
|
||||||
|
(any (lambda (scope)
|
||||||
|
;; XXX: Add regex support?
|
||||||
|
(string-prefix? scope file))
|
||||||
|
(team-scope team)))
|
||||||
|
files)
|
||||||
|
(cons team acc)
|
||||||
|
acc))
|
||||||
|
'()
|
||||||
|
%teams))
|
||||||
|
|
||||||
(define (cc . teams)
|
(define (cc . teams)
|
||||||
"Return arguments for `git send-email' to notify the members of the given
|
"Return arguments for `git send-email' to notify the members of the given
|
||||||
TEAMS when a patch is received by Debbugs."
|
TEAMS when a patch is received by Debbugs."
|
||||||
|
@ -297,7 +320,7 @@ TEAMS when a patch is received by Debbugs."
|
||||||
(team-members team)))
|
(team-members team)))
|
||||||
|
|
||||||
(define (list-teams)
|
(define (list-teams)
|
||||||
"Print all teams and their members."
|
"Print all teams, their scope and their members."
|
||||||
(define port* (current-output-port))
|
(define port* (current-output-port))
|
||||||
(define width* (%text-width))
|
(define width* (%text-width))
|
||||||
(hash-for-each
|
(hash-for-each
|
||||||
|
@ -307,7 +330,7 @@ TEAMS when a patch is received by Debbugs."
|
||||||
id: ~a
|
id: ~a
|
||||||
name: ~a
|
name: ~a
|
||||||
description: ~a
|
description: ~a
|
||||||
members:
|
~amembers:
|
||||||
"
|
"
|
||||||
(team-id team)
|
(team-id team)
|
||||||
(team-name team)
|
(team-name team)
|
||||||
|
@ -316,15 +339,48 @@ members:
|
||||||
(string->recutils
|
(string->recutils
|
||||||
(fill-paragraph text width*
|
(fill-paragraph text width*
|
||||||
(string-length "description: ")))))
|
(string-length "description: ")))))
|
||||||
"<none>"))
|
"<none>")
|
||||||
|
(match (team-scope team)
|
||||||
|
(() "")
|
||||||
|
(scope (format #f "scope: ~{~s ~}~%" scope))))
|
||||||
(list-members team port* "+ ")
|
(list-members team port* "+ ")
|
||||||
(newline))
|
(newline))
|
||||||
%teams))
|
%teams))
|
||||||
|
|
||||||
|
|
||||||
|
(define (diff-revisions rev-start rev-end)
|
||||||
|
"Return the list of added, modified or removed files between REV-START
|
||||||
|
and REV-END, two git revision strings."
|
||||||
|
(let* ((repository (repository-open (getcwd)))
|
||||||
|
(commit1 (commit-lookup repository
|
||||||
|
(object-id
|
||||||
|
(revparse-single repository rev-start))))
|
||||||
|
(commit2 (commit-lookup repository
|
||||||
|
(object-id
|
||||||
|
(revparse-single repository rev-end))))
|
||||||
|
(diff (diff-tree-to-tree repository
|
||||||
|
(commit-tree commit1)
|
||||||
|
(commit-tree commit2)))
|
||||||
|
(files '()))
|
||||||
|
(diff-foreach
|
||||||
|
diff
|
||||||
|
(lambda (delta progress)
|
||||||
|
(set! files
|
||||||
|
(cons (diff-file-path (diff-delta-old-file delta)) files))
|
||||||
|
0)
|
||||||
|
(const 0)
|
||||||
|
(const 0)
|
||||||
|
(const 0))
|
||||||
|
files))
|
||||||
|
|
||||||
|
|
||||||
(define (main . args)
|
(define (main . args)
|
||||||
(match args
|
(match args
|
||||||
(("cc" . team-names)
|
(("cc" . team-names)
|
||||||
(apply cc (map find-team team-names)))
|
(apply cc (map find-team team-names)))
|
||||||
|
(("cc-members" rev-start rev-end)
|
||||||
|
(apply cc (find-team-by-scope
|
||||||
|
(diff-revisions rev-start rev-end))))
|
||||||
(("list-teams" . args)
|
(("list-teams" . args)
|
||||||
(list-teams))
|
(list-teams))
|
||||||
(("list-members" . team-names)
|
(("list-members" . team-names)
|
||||||
|
|
Reference in New Issue