projects/guix·blob javascript-team · refs

2041 lines · 71.5 KiB

1#!/bin/sh
2# -*- mode: scheme; -*-
3# Extra care is taken here to ensure this script can run in most environments,
4# since it is invoked by 'git send-email'.
5pre_inst_env_maybe=
6command -v guix > /dev/null || pre_inst_env_maybe=./pre-inst-env
7exec $pre_inst_env_maybe guix repl -- "$0" "$@"
8!#
9
10;;; GNU Guix --- Functional package management for GNU
11;;; Copyright © 2022-2024 Ricardo Wurmus <[email protected]>
12;;; Copyright © 2022 Mathieu Othacehe <[email protected]>
13;;; Copyright © 2022, 2023, 2025 Maxim Cournoyer <[email protected]>
14;;; Copyright © 2022 Simon Tournier <[email protected]>
15;;; Copyright © 2025 Jelle Licht <[email protected]>
16;;; Copyright © 2025 Cayetano Santos <[email protected]>
17;;; Copyright © 2025-2026 Ludovic Courtès <[email protected]>
18;;; Copyright © 2025 jgart <[email protected]>
19;;; Copyright © 2026 Denis 'GNUtoo' Carikli <[email protected]>
20;;;
21;;; This file is part of GNU Guix.
22;;;
23;;; GNU Guix is free software; you can redistribute it and/or modify it
24;;; under the terms of the GNU General Public License as published by
25;;; the Free Software Foundation; either version 3 of the License, or (at
26;;; your option) any later version.
27;;;
28;;; GNU Guix is distributed in the hope that it will be useful, but
29;;; WITHOUT ANY WARRANTY; without even the implied warranty of
30;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
31;;; GNU General Public License for more details.
32;;;
33;;; You should have received a copy of the GNU General Public License
34;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
35
36;;; Commentary:
37
38;; This code defines development teams and team members, as well as their
39;; scope.
40
41;;; Code:
42
43(define-module (teams)
44 #:use-module (srfi srfi-1)
45 #:use-module (srfi srfi-9)
46 #:use-module (srfi srfi-26)
47 #:use-module (srfi srfi-34)
48 #:use-module (srfi srfi-35)
49 #:use-module (srfi srfi-71)
50 #:use-module (ice-9 format)
51 #:use-module (ice-9 regex)
52 #:use-module (ice-9 match)
53 #:use-module (ice-9 rdelim)
54 #:use-module (guix ui)
55 #:use-module (git)
56 #:use-module (json)
57 #:use-module (web client)
58 #:use-module (web request)
59 #:use-module (web response)
60 #:use-module (rnrs bytevectors)
61 #:use-module (guix base64))
62
63(define-record-type <regexp*>
64 (%make-regexp* pat flag rx)
65 regexp*?
66 (pat regexp*-pattern)
67 (flag regexp*-flag)
68 (rx regexp*-rx))
69
70;;; Work around regexp implementation.
71;;; This record allows to track the regexp pattern and then display it.
72(define* (make-regexp* pat #:optional (flag regexp/extended))
73 "Alternative to `make-regexp' producing annotated <regexp*> objects."
74 (%make-regexp* pat flag (make-regexp pat flag)))
75
76(define (regexp*-exec rx* str)
77 "Execute the RX* regexp, a <regexp*> object."
78 (regexp-exec (regexp*-rx rx*) str))
79
80(define-record-type <team>
81 (make-team id name description members scope)
82 team?
83 (id team-id)
84 (name team-name)
85 (description team-description)
86 (members team-members set-team-members!)
87 (scope team-scope))
88
89(define-record-type <person>
90 (make-person name email account)
91 person?
92 (name person-name)
93 (email person-email)
94 (account person-codeberg-account))
95
96(define (person name email account)
97 (make-person name email account))
98
99(define* (team id #:key name description (members '())
100 (scope '()))
101 (make-team id
102 (or name (symbol->string id))
103 description
104 members
105 scope))
106
107(define %teams
108 (make-hash-table))
109
110(define-syntax define-team
111 (lambda (x)
112 (syntax-case x ()
113 ((_ id value)
114 #`(begin
115 (define-public id value)
116 (hash-set! %teams 'id id))))))
117
118(define-syntax-rule (define-member person teams ...)
119 (let ((p person))
120 (for-each (lambda (team-id)
121 (let ((team
122 (hash-ref %teams team-id
123 (lambda ()
124 (error (format #false
125 "Unknown team ~a for ~a~%"
126 team-id p))))))
127 (set-team-members!
128 team (cons p (team-members team)))))
129 (quote (teams ...)))))
130
131
132;;;
133;;; Forgejo support.
134;;;
135
136(define-json-mapping <forgejo-validation-error>
137 forgejo-validation-error forgejo-validation-error?
138 json->forgejo-validation-error
139 (message forgejo-validation-error-message)
140 (url forgejo-validation-error-url))
141
142;; Forgejo team. This corresponds to both the 'Team' and 'CreateTeamOption'
143;; structures in Forgejo.
144(define-json-mapping <forgejo-team>
145 forgejo-team forgejo-team?
146 json->forgejo-team <=> forgejo-team->json
147 (name forgejo-team-name)
148 (id forgejo-team-id) ;integer | *unspecified*
149 (description forgejo-team-description)
150 (all-repositories? forgejo-team-all-repositories?
151 "includes_all_repositories")
152 (can-create-org-repository? forgejo-team-can-create-org-repository?
153 "can_create_org_repo")
154 (permission forgejo-team-permission
155 "permission" string->symbol symbol->string)
156 ;; A 'units' field exists but is deprecated in favor of 'units_map'.
157 (unit-map forgejo-team-unit-map
158 "units_map" json->unit-map unit-map->json))
159
160(define (unit-map->json lst)
161 (map (match-lambda
162 ((unit . permission)
163 (cons unit (symbol->string permission))))
164 lst))
165
166(define (json->unit-map lst)
167 (map (match-lambda
168 ((unit . permission)
169 (cons unit (string->symbol permission))))
170 lst))
171
172(define %default-forgejo-team-units
173 '("repo.code" "repo.issues" "repo.pulls" "repo.releases"
174 "repo.wiki" "repo.ext_wiki" "repo.ext_issues" "repo.projects"
175 "repo.packages" "repo.actions"))
176
177(define %default-forgejo-team-unit-map
178 ;; Everything (including "repo.code") is read-only by default, except a few
179 ;; units.
180 (map (match-lambda
181 ("repo.pulls" (cons "repo.pulls" 'write))
182 ("repo.issues" (cons "repo.issues" 'write))
183 ("repo.wiki" (cons "repo.wiki" 'write))
184 (unit (cons unit 'read)))
185 %default-forgejo-team-units))
186
187;; Forgejo user, as returned by 'forgejo-team-members'.
188(define-json-mapping <forgejo-user>
189 forgejo-user forgejo-user?
190 json->forgejo-user <=> forgejo-user->json
191 (id forgejo-user-id) ;integer
192 (active? forgejo-user-active? "active") ;boolean
193 (login forgejo-user-login) ;string
194 (full-name forgejo-user-full-name "full_name") ;string
195 ;; Various fields omitted.
196 )
197
198(define (forgejo-http-headers token)
199 "Return the HTTP headers for basic authorization with TOKEN."
200 `((content-type . (application/json (charset . "UTF-8")))
201 ;; The "Auth Basic" scheme needs a base64-encoded colon-separated user and
202 ;; token values. Forgejo doesn't seem to care for the user part but the
203 ;; colon seems to be necessary for the token value to get extracted.
204 (authorization . (basic . ,(base64-encode
205 (string->utf8
206 (string-append ":" token)))))))
207
208;; Error with a Forgejo request.
209(define-condition-type &forgejo-error &error
210 forgejo-error?
211 (url forgejo-error-url)
212 (method forgejo-error-method)
213 (response forgejo-error-response)
214 (api-error forgejo-error-api-error))
215
216(define %codeberg-organization
217 ;; Name of the organization at codeberg.org.
218 "guix")
219
220(define* (codeberg-url items #:key (parameters '()))
221 "Construct a Codeberg API URL with the path components ITEMS and query
222PARAMETERS."
223 (define query
224 (match parameters
225 (() "")
226 (((keys . values) ...)
227 (string-append "?" (string-join
228 (map (lambda (key value)
229 (string-append key "=" value)) ;XXX: hackish
230 keys values)
231 "&")))))
232
233 (string-append "https://codeberg.org/api/v1/"
234 (string-join items "/")
235 query))
236
237(define-syntax process-url-components
238 (syntax-rules (&)
239 "Helper macro to construct a Codeberg URL."
240 ((_ components ... & parameters)
241 (codeberg-url (list components ...)
242 #:parameters parameters))
243 ((_ components ...)
244 (codeberg-url (list components ...)))))
245
246(define-syntax define-forgejo-request
247 (syntax-rules (=>)
248 "Define a procedure that performs a Forgejo request."
249 ((_ (proc parameters ...)
250 docstring
251 (verb components ...)
252 body
253 => code
254 deserialize)
255 (define (proc token parameters ...)
256 docstring
257 (let* ((url (process-url-components components ...))
258 (response port (http-request url
259 #:method 'verb
260 #:streaming? #t
261 #:headers (forgejo-http-headers token)
262 #:body body)))
263 (if (= code (response-code response))
264 (let ((value (deserialize port)))
265 (when port (close-port port))
266 value)
267 (let ((error (and (= 422 (response-code response))
268 port
269 (false-if-exception
270 (json->forgejo-validation-error port)))))
271 (when port (close-port port))
272 (raise (condition (&forgejo-error (url url)
273 (method 'verb)
274 (response response)
275 (api-error error)))))))))
276 ((_ (proc parameters ...)
277 docstring
278 (method components ...)
279 => code
280 deserialize)
281 (define-forgejo-request (proc parameters ...)
282 docstring
283 (method components ...)
284 ""
285 => code
286 deserialize))
287 ((_ (proc parameters ...)
288 docstring
289 (method components ...)
290 => code)
291 (define-forgejo-request (proc parameters ...)
292 docstring
293 (method components ...)
294 ""
295 => code
296 (const *unspecified*)))))
297
298;; API documentation at <https://codeberg.org/api/swagger>.
299
300(define-forgejo-request (organization-teams/paginated organization page)
301 "Return the list of teams of ORGANIZATION, for the given PAGE (1-indexed)."
302 (GET "orgs" organization "teams"
303 & `(("page" . ,(number->string page))))
304 => 200
305 (lambda (port)
306 (map json->forgejo-team (vector->list (json->scm port)))))
307
308(define (organization-teams token organization)
309 "Return the list of teams of ORGANIZATION."
310 (let loop ((index 1)
311 (pages '()))
312 (match (organization-teams/paginated token organization index)
313 (()
314 (concatenate (reverse pages)))
315 (lst
316 (loop (+ 1 index)
317 (cons lst pages))))))
318
319(define-forgejo-request (create-team organization team)
320 "Create TEAM, a Forgejo team, under ORGANIZATION."
321 (POST "orgs" organization "teams")
322 (forgejo-team->json team)
323 => 201
324 json->forgejo-team)
325
326(define-forgejo-request (edit-team team)
327 "Update TEAM, a Forgejo team."
328 (PATCH "teams" (number->string (forgejo-team-id team)))
329 (forgejo-team->json team)
330 => 200
331 json->forgejo-team)
332
333(define-forgejo-request (delete-team team)
334 "Delete TEAM, a Forgejo team."
335 (DELETE "teams" (number->string (forgejo-team-id team)))
336 => 204)
337
338(define-forgejo-request (forgejo-team-members team)
339 "Return the list of account names of the members of TEAM, a Forgejo team."
340 (GET "teams" (number->string (forgejo-team-id team)) "members"
341 & '(("limit" . "100"))) ;get up to 100 members
342 => 200
343 (lambda (port)
344 (set-port-encoding! port "UTF-8")
345 (map json->forgejo-user (vector->list (json->scm port)))))
346
347(define-forgejo-request (add-team-member team user)
348 "Add USER (a string) to TEAM, a Forgejo team.
349
350With recent versions of Forgejo, this sends an invitation to USER. This
351returns 409 when USER already got an invitation to join TEAM."
352 (PUT "teams" (number->string (forgejo-team-id team))
353 "members" user)
354 => 204)
355
356(define-forgejo-request (remove-team-member team user)
357 "Remove USER (a string) from TEAM, a Forgejo team."
358 (DELETE "teams" (number->string (forgejo-team-id team))
359 "members" user)
360 => 204)
361
362(define-forgejo-request (repository-teams owner repository)
363 "Return the list of teams assigned to REPOSITORY of OWNER."
364 (GET "repos" owner repository "teams"
365 & '(("limit" . "100"))) ;get up to 100 teams
366 => 200
367 (lambda (port)
368 (map json->forgejo-team (vector->list (json->scm port)))))
369
370(define-forgejo-request (add-repository-team owner repository team-name)
371 "Add TEAM-NAME as a team of OWNER's REPOSITORY."
372 (PUT "repos" owner repository "teams" team-name)
373 => 204)
374
375(define (team->forgejo-team team)
376 "Return a Forgejo team derived from TEAM, a <team> record."
377 (forgejo-team (team-id->forgejo-id (team-id team))
378 *unspecified* ;no numeric ID initially
379 (or (team-description team) "")
380 #f ;all-repositories?
381 #f ;can-create-org-repository?
382 'read ;permission
383 %default-forgejo-team-unit-map))
384
385(define* (update-team token forgejo-team team
386 #:key (log-port (current-error-port)))
387 "Update FORGEJO-TEAM on the server so that it matches TEAM."
388 (format log-port "updating team '~a'~%"
389 (forgejo-team-name forgejo-team))
390
391 ;; Update metadata: description, permissions, etc.
392 (edit-team token forgejo-team)
393
394 ;; Update the list of members so it matches those of TEAM.
395 (let* ((current (map forgejo-user-login
396 (forgejo-team-members token forgejo-team)))
397 (target (filter-map person-codeberg-account
398 (team-members team)))
399 (to-add (lset-difference string=? target current))
400 (to-remove (lset-difference string=? current target)))
401 (for-each (lambda (user)
402 (format log-port "adding '~a' to team '~a'~%"
403 user (forgejo-team-name forgejo-team))
404 ;; As per
405 ;; <https://codeberg.org/Codeberg/Community/issues/3167>,
406 ;; Forgejo 16 sends an invitation to join a team, rather than
407 ;; really adding the person to the team. When an invitation
408 ;; is already pending, it should return 409 (it would return
409 ;; 500 at one point).
410 (guard (c ((forgejo-error? c)
411 (let* ((response (forgejo-error-response c))
412 (code (response-code response))
413 (phrase (response-reason-phrase response)))
414 (if (= 409 code)
415 (format log-port "got ~a (~s): previous \
416membership invitation pending~%"
417 code phrase)
418 (raise c)))))
419 (add-team-member token forgejo-team user)))
420 to-add)
421 (for-each (lambda (user)
422 (format log-port "removing '~a' from team '~a'~%"
423 user (forgejo-team-name forgejo-team))
424 (remove-team-member token forgejo-team user))
425 to-remove)))
426
427(define* (synchronize-team token team
428 #:key
429 (current-teams
430 (organization-teams token
431 %codeberg-organization))
432 (log-port (current-error-port)))
433 "Synchronize TEAM, a <team> record, so that its metadata and list of members
434are accurate on Codeberg, either by creating it or by updating it if it
435already exists. Lookup team IDs among CURRENT-TEAMS."
436 (let ((forgejo-team
437 (find (let ((name (team-id->forgejo-id (team-id team))))
438 (lambda (candidate)
439 (string=? (forgejo-team-name candidate) name)))
440 current-teams)))
441 (if forgejo-team
442 (update-team token forgejo-team team
443 #:log-port log-port)
444 (let ((forgejo-team
445 (create-team token %codeberg-organization
446 (or forgejo-team
447 (team->forgejo-team team)))))
448 (format log-port "created team '~a'~%"
449 (forgejo-team-name forgejo-team))
450 (let ((members (filter-map person-codeberg-account
451 (team-members team))))
452 (for-each (lambda (member)
453 (add-team-member token forgejo-team member))
454 members)
455 (format log-port "added ~a members to team '~a'~%"
456 (length members)
457 (forgejo-team-name forgejo-team))
458 forgejo-team)))))
459
460(define (synchronize-teams token)
461 "Push all the existing teams on Codeberg."
462 (let ((teams (sort-teams
463 (hash-map->list (lambda (_ value) value) %teams))))
464 (format (current-error-port)
465 "creating ~a teams in the '~a' organization at Codeberg...~%"
466 (length teams) %codeberg-organization)
467
468 ;; Arrange to compute the list of existing teams once and for all.
469 (for-each (let ((teams (organization-teams token
470 %codeberg-organization)))
471 (lambda (team)
472 (synchronize-team token team
473 #:current-teams teams)))
474 teams)
475
476 ;; Ensure all the teams are associated with the main repository.
477 (let ((repository-teams (repository-teams token
478 %codeberg-organization
479 "guix")))
480 (for-each (lambda (missing)
481 (format (current-error-port)
482 "adding team '~a' to '~a/guix'~%"
483 (team-id missing) %codeberg-organization)
484 (add-repository-team token %codeberg-organization "guix"
485 (team-id->forgejo-id
486 (team-id missing))))
487 (let ((names (map forgejo-team-name repository-teams)))
488 (remove (lambda (team)
489 (member (team-id->forgejo-id (team-id team))
490 names))
491 teams))))))
492
493
494
495(define-team ai
496 (team 'ai
497 #:name "Artificial Intelligence"
498 #:description "Packages related to AI, ML and LLM."
499 #:scope (list "gnu/packages/machine-learning.scm")))
500
501(define-team audio
502 (team 'audio
503 #:name "Audio team"
504 #:description "Audio related packages."
505 #:scope (list "gnu/packages/audio.scm"
506 "gnu/packages/fluidplug.scm"
507 "gnu/packages/music.scm"
508 "gnu/packages/xiph.scm")))
509
510(define-team beam
511 (team 'beam
512 #:name "Erlang/Elixir/BEAM team"
513 #:description "The virtual machine at the core of the Erlang Open
514Telecom Platform (OTP), Erlang and Elxir languages and packages, development
515of Rebar and Mix build systems and Hex.pm importer."
516 #:scope (list (make-regexp* "^gnu/packages/elixir(-.+|)\\.scm$")
517 "guix/build/mix-build-system.scm"
518 "guix/build-system/mix.scm"
519 (make-regexp* "^gnu/packages/erlang(-.+|)\\.scm$")
520 "guix/build/rebar-build-system.scm"
521 "guix/build-system/rebar.scm"
522 "guix/import/hexpm.scm"
523 "guix/scripts/import/hexpm.scm")))
524
525(define-team bioinformatics
526 (team 'bioinformatics
527 #:name "Bioinformatics team"
528 #:scope (list "gnu/packages/bioinformatics.scm")))
529
530(define-team bootstrap
531 (team 'bootstrap
532 #:name "Bootstrap"
533 #:description "Full-source bootstrap: stage0, Mes, Gash, etc."
534 #:scope (list "gnu/packages/bootstrap.scm"
535 "gnu/packages/commencement.scm"
536 "gnu/packages/mes.scm")))
537
538(define-team build-tools
539 (team 'build-tools
540 #:name "Build tools team"
541 #:description "Build tools and parser generators."
542 #:scope (list "gnu/packages/assembly.scm"
543 "gnu/packages/autogen.scm"
544 "gnu/packages/autotools.scm"
545 "gnu/packages/bison.scm"
546 "gnu/packages/compiler-tools.scm"
547 "gnu/packages/m4.scm"
548 "gnu/packages/oyacc.scm"
549 "gnu/packages/re2c.scm")))
550
551(define-team c++
552 (team 'c++
553 #:name "C/C++ team"
554 #:description
555 "C and C++ libraries and tools."
556 #:scope (list "gnu/build-system/cmake.scm"
557 "gnu/build/cmake-build-system.scm"
558 "gnu/packages/c.scm"
559 "gnu/packages/cmake.scm"
560 "gnu/packages/cpp.scm"
561 "gnu/packages/ninja.scm"
562 "gnu/packages/valgrind.scm")))
563
564(define-team chicken
565 (team 'chicken
566 #:name "Chicken Team"
567 #:description
568 "Chicken Scheme libraries and tools."
569 #:scope (list "gnu/build-system/chicken.scm"
570 "gnu/build/chicken-build-system.scm"
571 "gnu/packages/chicken.scm"
572 "guix/import/egg.scm")))
573
574(define-team codeberg
575 (team 'codeberg
576 #:name "Codeberg Project Owners"
577 #:description
578 "Hackers with Owner status on our Codeberg Organization"))
579
580(define-team community
581 (team 'community
582 #:name "Community"
583 #:description
584 "We focus on collaboration, project growth and future (social)
585challenges"))
586
587(define-team maintainers
588 (team 'maintainers
589 #:name "Maintainers"
590 #:description
591 "Looking after project policies, commit access and code of conduct
592reports."))
593
594(define-team core
595 (team 'core
596 #:name "Core / Tools / Internals"
597 #:scope
598 (list "etc/teams.scm"
599 "guix/avahi.scm"
600 "guix/base16.scm"
601 "guix/base32.scm"
602 "guix/base64.scm"
603 "guix/bzr-download.scm"
604 "guix/cache.scm"
605 "guix/channels.scm"
606 "guix/ci.scm"
607 "guix/colors.scm"
608 "guix/combinators.scm"
609 "guix/config.scm"
610 "guix/cpio.scm"
611 "guix/cpu.scm"
612 "guix/cve.scm"
613 "guix/cvs-download.scm"
614 "guix/deprecation.scm"
615 "guix/derivations.scm"
616 "guix/describe.scm"
617 "guix/diagnostics.scm"
618 "guix/discovery.scm"
619 "guix/docker.scm"
620 "guix/download.scm"
621 "guix/elf.scm"
622 "guix/fossil-download.scm"
623 "guix/ftp-client.scm"
624 "guix/gexp.scm"
625 "guix/git-authenticate.scm"
626 "guix/git-download.scm"
627 "guix/git.scm"
628 "guix/glob.scm"
629 "guix/gnu-maintenance.scm"
630 "guix/gnupg.scm"
631 "guix/grafts.scm"
632 "guix/graph.scm"
633 "guix/hash.scm"
634 "guix/hg-download.scm"
635 "guix/http-client.scm"
636 "guix/i18n.scm"
637 "guix/inferior.scm"
638 "guix/ipfs.scm"
639 "guix/least-authority.scm"
640 "guix/licenses.scm"
641 "guix/lint.scm"
642 "guix/man-db.scm"
643 "guix/memoization.scm"
644 "guix/modules.scm"
645 "guix/monad-repl.scm"
646 "guix/monads.scm"
647 "guix/narinfo.scm"
648 "guix/nar.scm"
649 "guix/openpgp.scm"
650 "guix/packages.scm"
651 "guix/pki.scm"
652 "guix/platform.scm"
653 "guix/profiles.scm"
654 "guix/profiling.scm"
655 "guix/progress.scm"
656 "guix/quirks.scm"
657 "guix/read-print.scm"
658 "guix/records.scm"
659 "guix/remote.scm"
660 "guix/remote-procedures.scm"
661 "guix/repl.scm"
662 "guix/search-paths.scm"
663 "guix/self.scm"
664 "guix/serialization.scm"
665 "guix/sets.scm"
666 "guix/ssh.scm"
667 "guix/status.scm"
668 "guix/store.scm"
669 "guix/substitutes.scm"
670 "guix/svn-download.scm"
671 "guix/swh.scm"
672 "guix/tests.scm"
673 "guix/transformations.scm"
674 "guix/ui.scm"
675 "guix/upstream.scm"
676 "guix/utils.scm"
677 "guix/workers.scm"
678 (make-regexp* "^guix/platforms/")
679 (make-regexp* "^guix/scripts/")
680 (make-regexp* "^guix/store/")
681 (make-regexp* "^nix/"))))
682
683(define-team core-packages
684 (team 'core-packages
685 #:name "Core packages"
686 #:description "Core packages: the GNU tool chain, Guile, Coreutils, etc."
687 #:scope (list "gnu/packages/base.scm"
688 "gnu/packages/bootstrap.scm"
689 "gnu/packages/commencement.scm"
690 "gnu/packages/cross-base.scm"
691 "gnu/packages/gcc.scm"
692 "gnu/packages/guile.scm"
693 "gnu/packages/ld-wrapper.in"
694 "gnu/packages/make-bootstrap.scm"
695 "gnu/packages/multiprecision.scm"
696 "guix/build/gnu-build-system.scm"
697 "guix/build/utils.scm"
698 "guix/build-system/gnu.scm")))
699
700(define-team debian
701 (team 'debian
702 #:name "Debian team"
703 #:description
704 "Packages related to Debian and Debian derivatives."
705 #:scope (list "gnu/packages/debian.scm")))
706
707(define-team documentation
708 (team 'documentation
709 #:name "Documentation"
710 #:description "Documentation: the manual and cookbook."
711 #:scope (list (make-regexp* "\\.texi$")
712 "doc/build.scm"
713 "gnu/system/examples/bare-bones.tmpl"
714 "gnu/system/examples/lightweight-desktop.tmpl"
715 "gnu/system/examples/desktop.tmpl")))
716
717(define-team dotnet
718 (team 'dotnet
719 #:name ".NET"
720 #:description ".NET programming environment."
721 #:scope (list "gnu/packages/dotnet.scm")))
722
723(define-team electronics
724 (team 'electronics
725 #:name "Electronics team"
726 #:description "Electronics and hardware related packages."
727 #:scope (list "gnu/packages/electronics.scm"
728 "gnu/packages/hdl.scm"
729 "gnu/packages/libftdi.scm"
730 "gnu/packages/engineering.scm"
731 "gnu/packages/flashing-tools.scm")))
732
733(define-team emacs
734 (team 'emacs
735 #:name "Emacs team"
736 #:description "The extensible, customizable text editor and its
737ecosystem."
738 #:scope (list "gnu/packages/aux-files/emacs/guix-emacs.el"
739 "gnu/packages/aux-files/emacs/comp-integrity.el"
740 (make-regexp* "^gnu/packages/emacs(-.+|)\\.scm$")
741 "gnu/packages/tree-sitter.scm"
742 "guix/build/emacs-build-system.scm"
743 "guix/build/emacs-utils.scm"
744 "guix/build-system/emacs.scm"
745 "guix/import/elpa.scm"
746 "guix/scripts/import/elpa.scm"
747 "tests/import/elpa.scm")))
748
749(define-team embedded
750 (team 'embedded
751 #:name "Embedded"
752 #:scope (list "gnu/packages/bootloaders.scm"
753 "gnu/packages/coreboot.scm"
754 "gnu/packages/embedded.scm"
755 "gnu/packages/firmware.scm")))
756
757(define-team games
758 (team 'games
759 #:name "Games and Toys"
760 #:description "Packaging programs for amusement."
761 #:scope (list "gnu/packages/emulators.scm"
762 "gnu/packages/games.scm"
763 "gnu/packages/game-development.scm"
764 "gnu/packages/luanti.scm"
765 "gnu/packages/esolangs.scm" ; granted, rather niche
766 "gnu/packages/motti.scm"
767 "gnu/services/games.scm"
768 "gnu/tests/games.scm"
769 "guix/build/luanti-build-system.scm")))
770
771(define-team gnome
772 (team 'gnome
773 #:name "Gnome team"
774 #:description
775 "The Gnome desktop environment, along with core technologies such as
776GLib/GIO, GTK, GStreamer and Webkit."
777 #:scope (list (make-regexp* "etc/teams/gnome")
778 "gnu/packages/glib.scm"
779 "gnu/packages/gstreamer.scm"
780 "gnu/packages/gtk.scm"
781 "gnu/packages/gnome.scm"
782 "gnu/packages/gnome-circle.scm"
783 "gnu/packages/gnome-xyz.scm"
784 "gnu/packages/webkit.scm"
785 "gnu/services/desktop.scm"
786 "guix/build/glib-or-gtk-build-system.scm"
787 "guix/build/meson-build-system.scm")))
788
789(define-team go
790 (team 'go
791 #:name "Go team"
792 #:scope (list "gnu/packages/configuration-management.scm"
793 (make-regexp* "gnu/packages/golang(-.+|)\\.scm$")
794 "gnu/packages/syncthing.scm"
795 "gnu/packages/terraform.scm"
796 "guix/build-system/go.scm"
797 "guix/build/go-build-system.scm"
798 "guix/import/go.scm"
799 "guix/scripts/import/go.scm"
800 "tests/import/go.scm")))
801
802(define-team guile
803 (team 'guile
804 #:name "Guile team"
805 #:description
806 "Team for the Guile platform, libraries, and build system."
807 #:scope (list "gnu/packages/guile.scm"
808 "gnu/packages/guile-wm.scm"
809 "gnu/packages/guile-xyz.scm"
810 "guix/build-system/guile.scm"
811 "guix/build/guile-build-system.scm")))
812
813(define-team hare
814 (team 'hare
815 #:name "Hare"
816 #:scope (list "gnu/packages/hare.scm"
817 "gnu/packages/hare-apps.scm"
818 "gnu/packages/hare-xyz.scm"
819 "guix/build-system/hare.scm"
820 "guix/build/hare-build-system.scm")))
821
822(define-team haskell
823 (team 'haskell
824 #:name "Haskell team"
825 #:description
826 "GHC, Hugs, Haskell packages, the \"hackage\" and \"stackage\" importers, and
827the haskell-build-system."
828 #:scope
829 (list "gnu/packages/dhall.scm"
830 ;; Match haskell.scm and haskell-*.scm.
831 (make-regexp* "^gnu/packages/haskell(-.+|)\\.scm$")
832 "gnu/packages/purescript.scm"
833 "guix/build/haskell-build-system.scm"
834 "guix/build-system/haskell.scm"
835 "guix/import/cabal.scm"
836 "guix/import/hackage.scm"
837 "guix/import/stackage.scm"
838 "guix/scripts/import/hackage.scm")))
839
840(define-team home
841 (team 'home
842 #:name "Team for \"Guix Home\""
843 #:scope (list (make-regexp* "^(gnu|guix/scripts)/home(\\.scm$|/)")
844 "tests/guix-home.sh"
845 "tests/home-import.scm"
846 "tests/home-services.scm")))
847
848(define-team hpc
849 (team 'hpc
850 #:name "High-performance computing team"
851 #:description "High-performance computing (HPC) related packages."
852 #:scope (list "gnu/packages/fabric-management.scm"
853 "gnu/packages/mpi.scm"
854 "gnu/packages/oneapi.scm"
855 "gnu/packages/opencl.scm"
856 "gnu/packages/parallel.scm"
857 "gnu/packages/rocm.scm"
858 "gnu/packages/rocm-apps.scm"
859 "gnu/packages/rocm-tools.scm"
860 "gnu/packages/rocm-libs.scm"
861 "gnu/packages/sycl.scm"
862 "gnu/packages/tbb.scm"
863 "gnu/packages/vulkan.scm")))
864
865(define-team hurd
866 (team 'hurd
867 #:name "Team for the Hurd"
868 #:description "GNU Hurd packages and operating system support."
869 #:scope (list "gnu/system/hurd.scm"
870 "gnu/system/images/hurd.scm"
871 "gnu/build/hurd-boot.scm"
872 "gnu/services/hurd.scm"
873 "gnu/packages/hurd.scm")))
874
875(define-team installer
876 (team 'installer
877 #:name "Installer script and system installer"
878 #:scope (list (make-regexp* "^gnu/installer(\\.scm$|/)"))))
879
880(define-team java
881 (team 'java
882 #:name "Java and Maven team"
883 #:description
884 "The JDK and JRE, the Maven build system, Java packages, the ant-build-system,
885and the maven-build-system."
886 #:scope
887 (list "gnu/packages/clojure.scm"
888 ;; Match java.scm and java-*.scm.
889 (make-regexp* "^gnu/packages/java(-.+|)\\.scm$")
890 ;; Match maven.scm and maven-*.scm
891 (make-regexp* "^gnu/packages/maven(-.+|)\\.scm$")
892 "gnu/packages/netbeans.scm"
893 "guix/build/ant-build-system.scm"
894 "guix/build/clojure-build-system.scm"
895 "guix/build/clojure-utils.scm"
896 "guix/build/java-utils.scm"
897 "guix/build/maven-build-system.scm"
898 ;; The maven directory
899 (make-regexp* "^guix/build/maven/")
900 "guix/build-system/ant.scm"
901 "guix/build-system/clojure.scm"
902 "guix/build-system/maven.scm")))
903
904(define-team javascript
905 (team 'javascript
906 #:name "JavaScript team"
907 #:description
908 "JavaScript/Node.js packages, the node build system."
909 #:scope (list "gnu/packages/javascript.scm"
910 "gnu/packages/node-xyz.scm"
911 "gnu/packages/node.scm"
912 "guix/build-system/node.scm"
913 "guix/build/json-utils.scm"
914 "guix/build/node-build-system.scm"
915 "guix/import/npm-binary.scm"
916 "guix/scripts/import/npm-binary.scm"
917 "tests/json-utils.scm")))
918
919(define-team julia
920 (team 'julia
921 #:name "Julia team"
922 #:description
923 "The Julia language, Julia packages, and the julia-build-system."
924 #:scope (list (make-regexp* "^gnu/packages/julia(-.+|)\\.scm$")
925 "guix/build/julia-build-system.scm"
926 "guix/build-system/julia.scm")))
927
928(define-team kde
929 (team 'kde
930 #:name "KDE team"
931 #:description
932 "The plasma desktop environment, and KDE Applications."
933 #:scope (list (make-regexp* "^gnu/packages/(kde)(-.+|)\\.scm$"))))
934
935(define-team linux-libre
936 (team 'linux-libre
937 #:name "Linux-libre kernel team"
938 #:scope (list "gnu/build/linux-modules.scm"
939 (make-regexp* "^gnu/packages/aux-files/linux-libre.*$")
940 "gnu/packages/linux.scm"
941 "gnu/tests/linux-modules.scm"
942 "guix/build/linux-module-build-system.scm"
943 "guix/build-system/linux-module.scm"
944 "etc/manifests/kernels.scm")))
945
946(define-team lisp
947 (team 'lisp
948 #:name "Lisp team"
949 #:description
950 "Common Lisp and similar languages, Common Lisp packages and the
951asdf-build-system."
952 #:scope (list (make-regexp* "^gnu/packages/lisp(-.+|)\\.scm$")
953 "guix/build/asdf-build-system.scm"
954 "guix/build/lisp-utils.scm"
955 "guix/build-system/asdf.scm")))
956
957(define-team localization
958 (team 'localization
959 #:name "Localization (l10n) team"
960 #:description
961 "Localization of your system to specific languages."
962 #:scope (list "gnu/packages/anthy.scm"
963 "gnu/packages/fcitx5.scm"
964 "gnu/packages/fonts.scm"
965 "gnu/packages/ibus.scm")))
966
967(define-team lua
968 (team 'lua
969 #:name "Lua team"
970 #:description
971 "Lua, Fennel, and related packages."
972 #:scope (list "gnu/packages/lua.scm"
973 "gnu/packages/luanti.scm")))
974
975(define-team lxqt
976 (team 'lxqt
977 #:name "LXQt team"
978 #:description "LXQt desktop environment."
979 #:scope (list "gnu/packages/lxqt.scm")))
980
981(define-team mate
982 (team 'mate
983 #:name "MATE team"
984 #:description "MATE desktop environment"
985 #:scope (list "gnu/packages/mate.scm")))
986
987(define-team mentors
988 (team 'mentors
989 #:name "Mentors"
990 #:description
991 "A group of mentors who chaperone contributions by newcomers."))
992
993(define-team mozilla
994 (team 'mozilla
995 #:name "Mozilla"
996 #:description
997 "Taking care of Icedove and Web Browsers based on Mozilla Thunderbird
998and Firefox."
999 #:scope (list "gnu/build/icecat-extension.scm"
1000 "gnu/packages/browser-extensions.scm"
1001 "gnu/packages/gnuzilla.scm"
1002 "gnu/packages/librewolf.scm"
1003 "gnu/packages/tor-browsers.scm")))
1004
1005(define-team ocaml
1006 (team 'ocaml
1007 #:name "OCaml and Dune team"
1008 #:description
1009 "The OCaml language, the Dune build system, OCaml packages, the \"opam\"
1010importer, and the ocaml-build-system."
1011 #:scope
1012 (list "gnu/packages/ocaml.scm"
1013 "gnu/packages/coq.scm"
1014 "gnu/packages/rocq.scm"
1015 "guix/build/ocaml-build-system.scm"
1016 "guix/build/dune-build-system.scm"
1017 "guix/build-system/ocaml.scm"
1018 "guix/build-system/dune.scm"
1019 "guix/import/opam.scm"
1020 "guix/scripts/import/opam.scm"
1021 "tests/import/opam.scm")))
1022
1023(define-team perl
1024 (team 'perl
1025 #:name "Perl and Raku team"
1026 #:description
1027 "Perl & Raku packages, the \"cpan\" importer, and the
1028perl-build-system as well as the rakudo-build-system."
1029 #:scope
1030 (list (make-regexp* "^gnu/packages/perl(-.+|)\\.scm$")
1031 "guix/build/perl-build-system.scm"
1032 "guix/build/rakudo-build-system.scm"
1033 "guix/build-system/perl.scm"
1034 "guix/build-system/rakudo.scm"
1035 "guix/import/cpan.scm"
1036 "guix/scripts/import/cpan.scm")))
1037
1038(define-team python
1039 (team 'python
1040 #:name "Python team"
1041 #:description
1042 "Python, Python packages, the \"pypi\" importer, and the python-build-system."
1043 #:scope
1044 (list (make-regexp* "^gnu/packages/aux-files/python/.*\\.py$")
1045 "gnu/packages/django.scm"
1046 "gnu/packages/jupyter.scm"
1047 (make-regexp* "^gnu/packages/python(-.+|)\\.scm$")
1048 "gnu/packages/sphinx.scm"
1049 "gnu/packages/tryton.scm"
1050 "guix/build-system/pyproject.scm"
1051 "guix/build-system/python.scm"
1052 "guix/build/pyproject-build-system.scm"
1053 "guix/build/python-build-system.scm"
1054 "guix/build/toml.scm" ;temporary, until other build system will use it
1055 "guix/import/pypi.scm"
1056 "guix/scripts/import/pypi.scm"
1057 "tests/import/pypi.scm"
1058 "tests/toml.scm")))
1059
1060(define-team qa-packages
1061 (team 'qa-packages
1062 #:name "Team for quality assurance packages"
1063 #:description
1064 "Quality assurance software (CI/CD, testing, analysis;
1065no direct relation to Guix's QA)."
1066 #:scope (list "gnu/packages/benchmark.scm"
1067 "gnu/packages/check.scm"
1068 "gnu/packages/ci.scm"
1069 "gnu/packages/code.scm"
1070 "gnu/packages/debug.scm"
1071 "gnu/packages/dezyne.scm"
1072 "gnu/packages/libunwind.scm"
1073 "gnu/services/ci.scm"
1074 "gnu/tests/ci.scm")))
1075
1076(define-team qt
1077 (team 'qt
1078 #:name "Qt team"
1079 #:description
1080 "The Qt toolkit/library and the qt-build-system,
1081as well as some packages using Qt."
1082 #:scope (list "gnu/packages/qt.scm"
1083 "guix/build-system/qt.scm"
1084 "guix/build/qt-build-system.scm"
1085 "guix/build/qt-utils.scm")))
1086
1087(define-team r
1088 (team 'r
1089 #:name "R team"
1090 #:description
1091 "The R language, CRAN and Bioconductor repositories, the \"cran\" importer,
1092and the r-build-system."
1093 #:scope (list "gnu/packages/bioconductor.scm"
1094 "gnu/packages/cran.scm"
1095 "guix/build/r-build-system.scm"
1096 "guix/build-system/r.scm"
1097 "guix/import/cran.scm"
1098 "guix/scripts/import/cran.scm"
1099 "tests/import/cran.scm")))
1100
1101(define-team racket
1102 (team 'racket
1103 #:name "Racket team"
1104 #:description
1105 "The Racket language and Racket-based languages, Racket packages,
1106Racket's variant of Chez Scheme, and development of a Racket build system and
1107importer."
1108 #:scope (list "gnu/packages/chez.scm"
1109 "gnu/packages/racket.scm")))
1110
1111(define-team release
1112 (team 'release
1113 #:name "Release team"
1114 #:description
1115 "The current release team. Members are expected to change with each
1116release."
1117 #:scope (list "NEWS"
1118 (make-regexp* "^etc/manifests/release-.+\\.scm$")
1119 (make-regexp* "^etc/teams/release/"))))
1120
1121(define-team reproduciblebuilds
1122 (team 'reproduciblebuilds
1123 #:name "Reproducible Builds team"
1124 #:description
1125 "Reproducible Builds tooling and issues that affect any guix packages."
1126 #:scope (list "gnu/packages/diffoscope.scm")))
1127
1128(define-team ruby
1129 (team 'ruby
1130 #:name "Ruby team"
1131 #:scope (list (make-regexp* "^gnu/packages/(ruby)(-.+|)\\.scm$")
1132 "guix/build/ruby-build-system.scm"
1133 "guix/build-system/ruby.scm"
1134 "guix/import/gem.scm"
1135 "guix/scripts/import/gem.scm"
1136 "tests/import/gem.scm")))
1137
1138(define-team rust
1139 (team 'rust
1140 #:name "Rust"
1141 #:scope (list (make-regexp* "^gnu/packages/(crates|rust)(-.+|)\\.scm$")
1142 "gnu/packages/sequoia.scm"
1143 "guix/build/cargo-build-system.scm"
1144 "guix/build/cargo-utils.scm"
1145 "guix/build-system/cargo.scm"
1146 "guix/import/crate.scm"
1147 "guix/import/crate/cargo-lock.scm"
1148 "guix/scripts/import/crate.scm"
1149 "tests/import/crate.scm")))
1150
1151(define-team crypto
1152 (team 'crypto
1153 #:name "Crypto team"
1154 #:description
1155 "Secrets, passwords, cryptography and security related packages."
1156 #:scope (list (make-regexp* "^gnu/packages/(.*-|)crypto\\.scm$")
1157 "gnu/packages/cryptsetup.scm"
1158 "gnu/packages/cybersecurity.scm"
1159 "gnu/packages/gnupg.scm"
1160 "gnu/packages/nettle.scm"
1161 "gnu/packages/password-utils.scm"
1162 "gnu/packages/security-token.scm"
1163 "gnu/packages/ssh.scm"
1164 "gnu/packages/tls.scm"
1165 "gnu/packages/vpn.scm")))
1166
1167(define-team science
1168 (team 'science
1169 #:name "Science team"
1170 #:description "The main science disciplines and fields related
1171packages (e.g. Astronomy, Chemistry, Math, Physics etc.)"
1172 #:scope (list (make-regexp* "^gnu/packages/fortran(-.+|)\\.scm$")
1173 "gnu/packages/algebra.scm"
1174 "gnu/packages/astronomy.scm"
1175 "gnu/packages/chemistry.scm"
1176 "gnu/packages/geo.scm"
1177 "gnu/packages/graph.scm"
1178 "gnu/packages/lean.scm"
1179 "gnu/packages/maths.scm"
1180 "gnu/packages/medical.scm"
1181 "gnu/packages/physics.scm"
1182 "gnu/packages/sagemath.scm"
1183 "gnu/packages/statistics.scm")))
1184
1185(define-team security-response
1186 (team 'security-response
1187 #:name "Guix security response team"
1188 #:description "Security response team: \
1189https://guix.gnu.org/security/ ."))
1190
1191(define-team sugar
1192 (team 'sugar
1193 #:name "Sugar team"
1194 #:description
1195 "Everything related to the Sugar Desktop and learning environment."
1196 #:scope (list "gnu/packages/sugar.scm")))
1197
1198(define-team sysadmin
1199 (team 'sysadmin
1200 #:name "Sysadmin team"
1201 #:description
1202 "Networking, server clustering, high availability."
1203 #:scope (list "gnu/packages/admin.scm"
1204 "gnu/packages/acl.scm"
1205 "gnu/packages/adns.scm"
1206 "gnu/packages/antivirus.scm"
1207 "gnu/packages/apparmor.scm"
1208 "gnu/packages/authentication.scm"
1209 "gnu/packages/cluster.scm"
1210 "gnu/packages/configuration-management.scm"
1211 "gnu/packages/databases.scm"
1212 "gnu/packages/distributed.scm"
1213 "gnu/packages/dns.scm"
1214 "gnu/packages/high-availability.scm"
1215 "gnu/packages/kerberos.scm"
1216 "gnu/packages/logging.scm"
1217 "gnu/packages/monitoring.scm"
1218 "gnu/packages/nfs.scm"
1219 "gnu/packages/openldap.scm"
1220 "gnu/packages/openstack.scm"
1221 "gnu/packages/prometheus.scm"
1222 "gnu/packages/rdesktop.scm"
1223 "gnu/packages/samba.scm"
1224 "gnu/packages/selinux.scm"
1225 "gnu/packages/storage.scm"
1226 "gnu/packages/task-runners.scm"
1227 "gnu/packages/terraform.scm"
1228 "gnu/packages/virtualization.scm"
1229 "gnu/packages/vnc.scm"
1230 "gnu/services/admin.scm"
1231 "gnu/services/authentication.scm"
1232 "gnu/services/databases.scm"
1233 "gnu/services/dns.scm"
1234 "gnu/services/high-availability.scm"
1235 "gnu/services/kerberos.scm"
1236 "gnu/services/monitoring.scm"
1237 "gnu/services/nfs.scm"
1238 "gnu/services/samba.scm"
1239 "gnu/services/virtualization.scm"
1240 "gnu/services/vnc.scm"
1241 "gnu/tests/databases.scm"
1242 "gnu/tests/dns.scm"
1243 "gnu/tests/high-availability.scm"
1244 "gnu/tests/monitoring.scm"
1245 "gnu/tests/nfs.scm"
1246 "gnu/tests/samba.scm"
1247 "gnu/tests/virtualization.scm"
1248 "gnu/tests/vnc.scm")))
1249
1250(define-team telephony
1251 (team 'telephony
1252 #:name "Telephony team"
1253 #:description
1254 "Telephony packages and services such as Jami, Linphone, etc."
1255 #:scope (list "gnu/build/jami-service.scm"
1256 "gnu/packages/jami.scm"
1257 "gnu/packages/linphone.scm"
1258 "gnu/packages/telephony.scm"
1259 "gnu/services/telephony.scm"
1260 "gnu/tests/data/jami-dummy-account.dat"
1261 "gnu/tests/telephony.scm"
1262 "tests/services/telephony.scm")))
1263
1264(define-team tex
1265 (team 'tex
1266 #:name "TeX team"
1267 #:description
1268 "TeX, LaTeX, XeLaTeX, LuaTeX, TeXLive, the texlive-build-system, and
1269the \"texlive\" importer."
1270 #:scope (list "gnu/packages/tex.scm"
1271 "gnu/packages/texlive.scm"
1272 "guix/build/texlive-build-system.scm"
1273 "guix/build-system/texlive.scm"
1274 "guix/import/texlive.scm"
1275 "guix/scripts/import/texlive.scm"
1276 "tests/import/texlive.scm")))
1277
1278(define-team translations
1279 (team 'translations
1280 #:name "Translations"
1281 #:scope (list "etc/news.scm"
1282 (make-regexp* "^po/"))))
1283
1284(define-team vcs
1285 (team 'vcs
1286 #:name "Version control team"
1287 #:description
1288 "Version control packages, services, and Guix download backends."
1289 #:scope (list "gnu/packages/version-control.scm"
1290 "gnu/services/version-control.scm"
1291 "gnu/tests/version-control.scm"
1292 "guix/build/bzr.scm"
1293 "guix/build/cvs.scm"
1294 "guix/build/fossil.scm"
1295 "guix/build/git.scm"
1296 "guix/build/hg.scm"
1297 "guix/build/svn.scm")))
1298
1299(define-team xfce
1300 (team 'xfce
1301 #:name "Xfce team"
1302 #:description "Xfce desktop environment."
1303 #:scope (list "gnu/packages/xfce.scm")))
1304
1305(define-team zig
1306 (team 'zig
1307 #:name "Zig team"
1308 #:description "Zig, Zig packages, and the zig-build system"
1309 #:scope (list "gnu/packages/zig.scm"
1310 "gnu/packages/zig-xyz.scm"
1311 "guix/build/zig-build-system.scm"
1312 "guix/build-system/zig.scm")))
1313
1314
1315(define-member (person "Anderson Torres"
1316 "[email protected]"
1317 "AndersonTorres")
1318 community translations)
1319
1320(define-member (person "Eric Bavier"
1321 "[email protected]"
1322 "bavier")
1323 science)
1324
1325(define-member (person "Jonathan Brielmaier"
1326 "[email protected]"
1327 "jonsger")
1328 mozilla)
1329
1330(define-member (person "Denis Carikli"
1331 "[email protected]"
1332 "GNUtoo")
1333 embedded)
1334
1335(define-member (person "Ludovic Courtès"
1336 "[email protected]"
1337 "civodul")
1338 codeberg core core-packages guile hpc installer)
1339
1340(define-member (person "Andreas Enge"
1341 "[email protected]"
1342 "enge")
1343 bootstrap c++ codeberg core-packages crypto lxqt science tex)
1344
1345(define-member (person "Tanguy Le Carrour"
1346 "[email protected]"
1347 "tanguybl")
1348 python home release)
1349
1350(define-member (person "Tobias Geerinckx-Rice"
1351 "[email protected]"
1352 "nckx")
1353 maintainers codeberg mentors)
1354
1355(define-member (person "Steve George"
1356 "[email protected]"
1357 "futurile")
1358 codeberg rust)
1359
1360(define-member (person "Leo Famulari"
1361 "[email protected]"
1362 "lfam")
1363 codeberg linux-libre)
1364
1365(define-member (person "Efraim Flashner"
1366 "[email protected]"
1367 "efraim")
1368 maintainers codeberg embedded bootstrap rust)
1369
1370(define-member (person "jgart"
1371 "[email protected]"
1372 "jgart")
1373 hare lisp mentors)
1374
1375(define-member (person "John Kehayias"
1376 "[email protected]"
1377 "podiki")
1378 security-response)
1379
1380(define-member (person "Guillaume Le Vaillant"
1381 "[email protected]"
1382 "glv")
1383 lisp)
1384
1385(define-member (person "Julien Lepiller"
1386 "[email protected]"
1387 "roptat")
1388 java ocaml translations)
1389
1390(define-member (person "Philip McGrath"
1391 "[email protected]"
1392 "LiberalArtist")
1393 racket)
1394
1395(define-member (person "Mathieu Othacehe"
1396 "[email protected]"
1397 "mothacehe")
1398 maintainers codeberg installer mentors)
1399
1400(define-member (person "Florian Pelz"
1401 "[email protected]"
1402 "pelzflorian")
1403 translations)
1404
1405(define-member (person "Liliana Marie Prikler"
1406 "[email protected]"
1407 "lilyp")
1408 emacs games gnome qa-packages)
1409
1410(define-member (person "Ricardo Wurmus"
1411 "[email protected]"
1412 "rekado")
1413 bioinformatics codeberg r sugar)
1414
1415(define-member (person "Christopher Baines"
1416 "[email protected]"
1417 "cbaines")
1418 codeberg core mentors ruby)
1419
1420(define-member (person "Andrew Tropin"
1421 "[email protected]"
1422 "abcdw")
1423 home emacs)
1424
1425(define-member (person "Trevor Richards"
1426 "[email protected]"
1427 "trevdev")
1428 emacs lisp)
1429
1430(define-member (person "pukkamustard"
1431 "[email protected]"
1432 "pukkamustard")
1433 ocaml)
1434
1435(define-member (person "Josselin Poiret"
1436 "[email protected]"
1437 "jpoiret")
1438 installer)
1439
1440(define-member (person "Simon Tournier"
1441 "[email protected]"
1442 "zimoun")
1443 julia core mentors r security-response)
1444
1445(define-member (person "宋文武"
1446 "[email protected]"
1447 "iyzsong")
1448 games localization lxqt qt xfce)
1449
1450(define-member (person "Vagrant Cascadian"
1451 "[email protected]"
1452 "vagrantc")
1453 debian embedded linux-libre)
1454
1455(define-member (person "Vagrant Cascadian" ;XXX: duplicate
1456 "[email protected]"
1457 "vagrantc")
1458 reproduciblebuilds)
1459
1460(define-member (person "Maxim Cournoyer"
1461 "[email protected]"
1462 "apteryx")
1463 maintainers codeberg core documentation electronics javascript gnome
1464 qt telephony)
1465
1466(define-member (person "Munyoki Kilyungi"
1467 "[email protected]"
1468 "BonfaceKilz")
1469 python guile)
1470
1471(define-member (person "Gabriel Wicki"
1472 "[email protected]"
1473 "gabber")
1474 audio community documentation electronics embedded)
1475
1476(define-member (person "Divya Ranjan Pattanaik"
1477 "[email protected]"
1478 "divyaranjan")
1479 emacs rust haskell)
1480
1481(define-member (person "Clément Lassieur"
1482 "[email protected]"
1483 "snape")
1484 mozilla)
1485
1486(define-member (person "Sharlatan Hellseher"
1487 "[email protected]"
1488 "Hellseher")
1489 bioinformatics go python science zig)
1490
1491(define-member (person "Arthur Rodrigues"
1492 "[email protected]"
1493 "arthurhdrodrigues")
1494 go zig)
1495
1496(define-member (person "Mark H Weaver"
1497 "[email protected]"
1498 "mhw")
1499 mozilla)
1500
1501(define-member (person "Laurent Gatto"
1502 "[email protected]"
1503 "lgatto")
1504 r bioinformatics)
1505
1506(define-member (person "Nicolas Goaziou"
1507 "[email protected]"
1508 "ngz")
1509 tex)
1510
1511(define-member (person "André Batista"
1512 "[email protected]"
1513 "madage")
1514 mozilla)
1515
1516(define-member (person "Janneke Nieuwenhuizen"
1517 "[email protected]"
1518 "janneke")
1519 bootstrap build-tools codeberg core-packages home hurd installer
1520 qa-packages)
1521
1522(define-member (person "Zheng Junjie"
1523 "[email protected]"
1524 "Z572")
1525 core-packages)
1526
1527(define-member (person "Sughosha"
1528 "[email protected]"
1529 "SameExpert")
1530 audio kde)
1531
1532(define-member (person "Jelle Licht"
1533 "[email protected]"
1534 "jlicht")
1535 javascript release)
1536
1537(define-member (person "Cayetano Santos"
1538 "[email protected]"
1539 "csantosb")
1540 ai emacs electronics hpc crypto reproduciblebuilds)
1541
1542(define-member (person "Greg Hogan"
1543 "[email protected]"
1544 "greghogan")
1545 c++)
1546
1547(define-member (person "Hilton Chain"
1548 "[email protected]"
1549 "hako"))
1550
1551(define-member (person "Noé Lopez"
1552 "[email protected]"
1553 "Baleine")
1554 gnome release)
1555
1556(define-member (person "Ashvith Shetty"
1557 "[email protected]"
1558 "Ashvith")
1559 javascript xfce)
1560
1561(define-member (person "Konrad Hinsen"
1562 "[email protected]"
1563 "khinsen")
1564 lisp)
1565
1566(define-member (person "Vinicius Monego"
1567 "[email protected]"
1568 "monego")
1569 python science)
1570
1571(define-member (person "Yelninei"
1572 "[email protected]"
1573 "Yelninei")
1574 hurd)
1575
1576(define-member (person "Giacomo Leidi"
1577 "[email protected]"
1578 "fishinthecalculator")
1579 audio beam)
1580
1581(define-member (person "Sören Tempel"
1582 "[email protected]"
1583 "nmeum")
1584 haskell)
1585
1586(define-member (person "Saku Laesvuori"
1587 "[email protected]"
1588 "slaesvuo")
1589 haskell)
1590
1591(define-member (person "Rodion Goritskov"
1592 "[email protected]"
1593 "rodion-goritskov")
1594 games java kde linux-libre)
1595
1596(define-member (person "Jason Conroy"
1597 "[email protected]"
1598 "conroj")
1599 ocaml)
1600
1601(define-member (person "Rutherther"
1602 "[email protected]"
1603 "Rutherther")
1604 core release)
1605
1606(define-member (person "Morgan Arnold"
1607 "[email protected]"
1608 "mra")
1609 core)
1610
1611(define-member (person "Danny Milosavljevic"
1612 "[email protected]"
1613 "daym")
1614 bootstrap dotnet hpc python rust science)
1615
1616(define-member (person "Andy Tai"
1617 "[email protected]"
1618 "atai")
1619 ai)
1620
1621(define-member (person "Pierre-Henry Fröhring"
1622 "[email protected]"
1623 "phfrohring")
1624 beam)
1625
1626(define-member (person "Nguyễn Gia Phong"
1627 "[email protected]"
1628 "cnx")
1629 build-tools lua qa-packages sysadmin vcs)
1630
1631(define-member (person "Lilah Tascheter"
1632 "[email protected]"
1633 "tinystar")
1634 hare)
1635
1636(define-member (person "FuncProgLinux"
1637 "[email protected]"
1638 "FuncProgLinux")
1639 mate)
1640
1641(define-member (person "Reza Housseini"
1642 "[email protected]"
1643 "rhou")
1644 python science c++)
1645
1646(define-member (person "Yunqi Shao"
1647 "[email protected]"
1648 "yqshao")
1649 sysadmin)
1650
1651(define-member (person "Collin Doering"
1652 "[email protected]"
1653 "rekahsoft")
1654 embedded electronics haskell sysadmin)
1655
1656(define-member (person "Mathieu Lirzin"
1657 "[email protected]"
1658 "mthl")
1659 java)
1660
1661(define-member (person "Hugo Buddelmeijer"
1662 "[email protected]"
1663 "hugobuddel")
1664 python security-response)
1665
1666(define-member (person "Yan Abu Arab"
1667 "[email protected]"
1668 "tux1c")
1669 python sysadmin)
1670
1671(define-member (person "Wilko Meyer"
1672 "[email protected]"
1673 "theesm")
1674 linux-libre perl)
1675
1676(define-member (person "Untrusem"
1677 "[email protected]"
1678 "untrusem")
1679 community mozilla)
1680
1681(define-member (person "David Thompson"
1682 "[email protected]"
1683 "flockofbirbs")
1684 guile)
1685
1686(define-member (person "Sergio Pastor Pérez"
1687 "[email protected]"
1688 "pastor")
1689 guile hpc kde)
1690
1691(define-member (person "Carlo Zancanaro"
1692 "[email protected]"
1693 "czan")
1694 lua ruby)
1695
1696(define-member (person "Folât Pjêrsômêj"
1697 "[email protected]"
1698 "folaht")
1699 documentation)
1700
1701(define-member (person "Ashish SHUKLA"
1702 "[email protected]"
1703 "group")
1704 vcs)
1705
1706(define-member (person "Spencer King"
1707 "[email protected]"
1708 "spencerking")
1709 julia)
1710
1711(define-member (person "Peter Polidoro"
1712 "[email protected]"
1713 "peterpolidoro")
1714 electronics)
1715
1716(define-member (person "Thomas Kramer"
1717 "[email protected]"
1718 "tok")
1719 electronics)
1720
1721(define-member (person "gemmaro"
1722 "[email protected]"
1723 "gemmaro")
1724 ruby)
1725
1726(define-member (person "bdunahu"
1727 "[email protected]"
1728 "bdunahu")
1729 games)
1730
1731(define-member (person "Nomike"
1732 "[email protected]"
1733 "nomike")
1734 dotnet)
1735
1736(define-member (person "Fabio Natali"
1737 "[email protected]"
1738 "fnat")
1739 emacs)
1740
1741(define-member
1742 (person "Arun Isaac"
1743 "[email protected]"
1744 "arunisaac")
1745 codeberg)
1746
1747(define-member (person "Florian Korbacher"
1748 "[email protected]"
1749 "SilverlightningY")
1750 audio)
1751
1752(define-member (person "Orahcio Felício de Sousa"
1753 "[email protected]"
1754 "orahcio")
1755 go python science)
1756
1757(define-member (person "Vivien Kraus"
1758 "[email protected]"
1759 "vivien")
1760 hpc)
1761
1762(define-member (person "Ghislain Vaillant"
1763 "[email protected]"
1764 "ghisvail")
1765 bioinformatics python science)
1766
1767(define-member (person "Dan Littlewood"
1768 "[email protected]"
1769 "danielittlewood")
1770 release)
1771
1772(define-member (person "Malte Frank Gerdes"
1773 "[email protected]"
1774 "mfg")
1775 chicken)
1776
1777
1778(define (find-team name)
1779 (or (hash-ref %teams (string->symbol name))
1780 (error (format #false
1781 "no such team: ~a~%" name))))
1782
1783(define (find-team-by-scope files)
1784 "Return the team(s) which scope matches at least one of the FILES, as list
1785of file names as string."
1786 (hash-fold
1787 (lambda (key team acc)
1788 (if (any (lambda (file)
1789 (any (match-lambda
1790 ((? string? scope)
1791 (string=? scope file))
1792 ((? regexp*? scope)
1793 (regexp*-exec scope file)))
1794 (team-scope team)))
1795 files)
1796 (cons team acc)
1797 acc))
1798 '()
1799 %teams))
1800
1801(define (cc . teams)
1802 "Return arguments for `git send-email' to notify the members of the given
1803TEAMS when a patch is received by Debbugs."
1804 (let ((members (append-map team-members teams)))
1805 (unless (null? members)
1806 (format #true "--add-header=\"X-Debbugs-Cc: ~{~a~^, ~}\""
1807 (map person-email (sort-members members))))))
1808
1809(define (sort-members members)
1810 "Deduplicate and sort MEMBERS alphabetically by their name."
1811 (sort (delete-duplicates members equal?)
1812 (lambda (m1 m2)
1813 (string<? (person-name m1) (person-name m2)))))
1814
1815(define (member->string member)
1816 "Return the 'email <name>' string representation of MEMBER."
1817 (let* ((name (person-name member))
1818 (quoted-name/maybe (if (string-contains name ",")
1819 (string-append "\"" name "\"")
1820 name)))
1821 (format #false "~a <~a>" quoted-name/maybe (person-email member))))
1822
1823(define* (list-members team #:key (prefix ""))
1824 "Print the members of the given TEAM."
1825 (for-each (lambda (member)
1826 (format #t "~a~a~%" prefix (member->string member)))
1827 (sort-members (team-members team))))
1828
1829(define (print-team team)
1830 "Print TEAM, a <team> record object."
1831 (format #t
1832 "\
1833id: ~a
1834name: ~a
1835description: ~a
1836~amembers:
1837"
1838 (team-id team)
1839 (team-name team)
1840 (or (and=> (team-description team)
1841 (lambda (text)
1842 (string->recutils
1843 (fill-paragraph text (%text-width)
1844 (string-length "description: ")))))
1845 "<none>")
1846 (match (team-scope team)
1847 (() "")
1848 (scope (format #f "scope:~%~{+ ~a~^~%~}~%"
1849 (sort (map (match-lambda
1850 ((? regexp*? rx)
1851 (regexp*-pattern rx))
1852 (item item))
1853 scope)
1854 string<?)))))
1855 (list-members team #:prefix "+ ")
1856 (newline))
1857
1858(define (sort-teams teams)
1859 "Sort TEAMS, a list of <team> record objects."
1860 (sort teams
1861 (lambda (team1 team2)
1862 (string<? (symbol->string (team-id team1))
1863 (symbol->string (team-id team2))))))
1864
1865(define* (list-teams #:optional team-names)
1866 "Print all teams, their scope and their members."
1867 (for-each print-team
1868 (sort-teams
1869 (if team-names
1870 (map find-team team-names)
1871 (hash-map->list (lambda (_ value) value) %teams)))))
1872
1873
1874(define (diff-revisions rev-start rev-end)
1875 "Return the list of added, modified or removed files between REV-START
1876and REV-END, two git revision strings."
1877 (let* ((repository (repository-open (getcwd)))
1878 (commit1 (commit-lookup repository
1879 (object-id
1880 (revparse-single repository rev-start))))
1881 (commit2 (commit-lookup repository
1882 (object-id
1883 (revparse-single repository rev-end))))
1884 (diff (diff-tree-to-tree repository
1885 (commit-tree commit1)
1886 (commit-tree commit2)))
1887 (files '()))
1888 (diff-foreach
1889 diff
1890 (lambda (delta progress)
1891 (set! files
1892 (cons (diff-file-path (diff-delta-old-file delta)) files))
1893 0)
1894 (const 0)
1895 (const 0)
1896 (const 0))
1897 files))
1898
1899(define (git-patch->commit-id file)
1900 "Parse the commit ID from FILE, a patch produced with git."
1901 (call-with-input-file file
1902 (lambda (port)
1903 (let loop ((line (read-line port)))
1904 (when (eof-object? line)
1905 (error "could not find 'from' commit in patch" file))
1906 (let ((m (string-match "^From ([0-9a-f]{40})" line)))
1907 (if m
1908 (match:substring m 1)
1909 (loop (read-line port))))))))
1910
1911(define (git-patch->revisions file)
1912 "Return the start and end revisions of FILE, a patch file produced with git."
1913 (let* ((rev-end (git-patch->commit-id file))
1914 (rev-start (string-append rev-end "^")))
1915 (list rev-start rev-end)))
1916
1917(define (patch->teams patch-file)
1918 "Return the name of the teams in scope for the changes in PATCH-FILE."
1919 (map (compose symbol->string team-id)
1920 (find-team-by-scope (apply diff-revisions
1921 (git-patch->revisions patch-file)))))
1922
1923(define (team-id->forgejo-id id)
1924 "Return a name (string) suitable as a Forgejo team name."
1925 (define valid ;"AlphaDashDot"
1926 (char-set-union char-set:ascii (char-set #\-) (char-set #\.)))
1927
1928 (define (valid? chr)
1929 (char-set-contains? valid chr))
1930
1931 (string-map (match-lambda
1932 (#\+ #\p) ;special case for "c++"
1933 ((? valid? chr) chr)
1934 (_ #\-))
1935 (symbol->string id)))
1936
1937(define (team->codeowners-snippet team)
1938 (string-join (map (lambda (scope)
1939 (format #f "~50a @guix/~a"
1940 (if (regexp*? scope)
1941 (let ((regexp (regexp*-pattern scope)))
1942 ;; Caret may not match as expected in
1943 ;; 'CODEOWNERS' so drop it.
1944 (if (string-prefix? "^" regexp)
1945 (string-drop regexp 1)
1946 regexp))
1947 (regexp-quote scope))
1948 (team-id->forgejo-id (team-id team))))
1949 (team-scope team))
1950 "\n"
1951 'suffix))
1952
1953(define (export-codeowners port)
1954 (let ((teams (sort-teams
1955 (hash-map->list (lambda (_ value) value) %teams))))
1956 (display "\
1957# This -*- conf -*- file was generated by './etc/teams.scm codeowners'.
1958#
1959# It describes the expected reviewers for a pull request based on the
1960# changed files. Unlike what the name of the file suggests they don't
1961# own the code (ownership is collective in this house!) but merely have
1962# a good understanding of that area of the codebase and therefore are
1963# usually suited as a reviewer.\n\n"
1964 port)
1965 (for-each (lambda (team)
1966 (let ((scope (team->codeowners-snippet team)))
1967 ;; Some teams, like Mentors and Community have no scope,
1968 ;; which would result in seemingly arbitrary newlines.
1969 (unless (string-null? scope)
1970 (display scope port)
1971 (newline port))))
1972 teams)))
1973
1974
1975(define (main . args)
1976 (match args
1977 (("cc" . team-names)
1978 (apply cc (map find-team team-names)))
1979 (("cc-all-team-members")
1980 (apply cc (hash-map->list (lambda (_ team) team) %teams)))
1981 (("cc-members" patch-file)
1982 (unless (file-exists? patch-file)
1983 (error "patch file does not exist:" patch-file))
1984 (apply main "cc-members" (git-patch->revisions patch-file)))
1985 (("cc-members" rev-start rev-end)
1986 (apply cc (find-team-by-scope
1987 (diff-revisions rev-start rev-end))))
1988 (("cc-members-header-cmd" patch-file)
1989 (let* ((teams (map find-team (patch->teams patch-file)))
1990 (members (sort-members (append-map team-members teams))))
1991 (unless (null? members)
1992 (format #true "X-Debbugs-Cc: ~{~a~^, ~}"
1993 (map member->string members)))))
1994 (("cc-mentors-header-cmd" patch-file)
1995 (format #true "X-Debbugs-Cc: ~{~a~^, ~}"
1996 (map member->string
1997 (sort-members (team-members (find-team "mentors"))))))
1998 (("get-maintainer" patch-file)
1999 (apply main "list-members" (patch->teams patch-file)))
2000 (("list-teams" . args)
2001 (list-teams))
2002 (("list-members" . team-names)
2003 (for-each
2004 (lambda (team-name)
2005 (list-members (find-team team-name)))
2006 team-names))
2007 (("show" . team-names)
2008 (list-teams team-names))
2009 (("codeowners")
2010 (export-codeowners (current-output-port)))
2011 (("sync-codeberg-teams" token)
2012 (synchronize-teams token))
2013 (anything
2014 (format (current-error-port)
2015 "Usage: etc/teams.scm <command> [<args>]
2016
2017Commands:
2018 cc <team-name>
2019 get git send-email flags for cc-ing <team-name>
2020 cc-members <start> <end> | <patch>
2021 cc teams related to files changed between revisions or in a patch file
2022 cc-all-team-members
2023 cc all members of all teams (useful in GCD processes)
2024 cc-members-header-cmd <patch>
2025 cc-members variant for use with 'git send-email --header-cmd'
2026 cc-mentors-header-cmd <patch>
2027 command to use with 'git send-email --header-cmd' to notify mentors
2028 list-teams
2029 list teams and their members
2030 list-members <team-name>
2031 list members belonging to <team-name>
2032 get-maintainer <patch>
2033 compatibility mode with Linux get_maintainer.pl
2034 show <team-name>
2035 display <team-name> properties
2036 codeowners
2037 write a 'CODEOWNERS' file suitable for Codeberg on standard output
2038 sync-codeberg-teams <token>
2039 create or update the list of teams at Codeberg~%"))))
2040
2041(apply main (cdr (command-line)))