projects/guix·blob python-team · refs

2024 lines · 71.0 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 codeberg
565 (team 'codeberg
566 #:name "Codeberg Project Owners"
567 #:description
568 "Hackers with Owner status on our Codeberg Organization"))
569
570(define-team community
571 (team 'community
572 #:name "Community"
573 #:description
574 "We focus on collaboration, project growth and future (social)
575challenges"))
576
577(define-team maintainers
578 (team 'maintainers
579 #:name "Maintainers"
580 #:description
581 "Looking after project policies, commit access and code of conduct
582reports."))
583
584(define-team core
585 (team 'core
586 #:name "Core / Tools / Internals"
587 #:scope
588 (list "etc/teams.scm"
589 "guix/avahi.scm"
590 "guix/base16.scm"
591 "guix/base32.scm"
592 "guix/base64.scm"
593 "guix/bzr-download.scm"
594 "guix/cache.scm"
595 "guix/channels.scm"
596 "guix/ci.scm"
597 "guix/colors.scm"
598 "guix/combinators.scm"
599 "guix/config.scm"
600 "guix/cpio.scm"
601 "guix/cpu.scm"
602 "guix/cve.scm"
603 "guix/cvs-download.scm"
604 "guix/deprecation.scm"
605 "guix/derivations.scm"
606 "guix/describe.scm"
607 "guix/diagnostics.scm"
608 "guix/discovery.scm"
609 "guix/docker.scm"
610 "guix/download.scm"
611 "guix/elf.scm"
612 "guix/fossil-download.scm"
613 "guix/ftp-client.scm"
614 "guix/gexp.scm"
615 "guix/git-authenticate.scm"
616 "guix/git-download.scm"
617 "guix/git.scm"
618 "guix/glob.scm"
619 "guix/gnu-maintenance.scm"
620 "guix/gnupg.scm"
621 "guix/grafts.scm"
622 "guix/graph.scm"
623 "guix/hash.scm"
624 "guix/hg-download.scm"
625 "guix/http-client.scm"
626 "guix/i18n.scm"
627 "guix/inferior.scm"
628 "guix/ipfs.scm"
629 "guix/least-authority.scm"
630 "guix/licenses.scm"
631 "guix/lint.scm"
632 "guix/man-db.scm"
633 "guix/memoization.scm"
634 "guix/modules.scm"
635 "guix/monad-repl.scm"
636 "guix/monads.scm"
637 "guix/narinfo.scm"
638 "guix/nar.scm"
639 "guix/openpgp.scm"
640 "guix/packages.scm"
641 "guix/pki.scm"
642 "guix/platform.scm"
643 "guix/profiles.scm"
644 "guix/profiling.scm"
645 "guix/progress.scm"
646 "guix/quirks.scm"
647 "guix/read-print.scm"
648 "guix/records.scm"
649 "guix/remote.scm"
650 "guix/remote-procedures.scm"
651 "guix/repl.scm"
652 "guix/search-paths.scm"
653 "guix/self.scm"
654 "guix/serialization.scm"
655 "guix/sets.scm"
656 "guix/ssh.scm"
657 "guix/status.scm"
658 "guix/store.scm"
659 "guix/substitutes.scm"
660 "guix/svn-download.scm"
661 "guix/swh.scm"
662 "guix/tests.scm"
663 "guix/transformations.scm"
664 "guix/ui.scm"
665 "guix/upstream.scm"
666 "guix/utils.scm"
667 "guix/workers.scm"
668 (make-regexp* "^guix/platforms/")
669 (make-regexp* "^guix/scripts/")
670 (make-regexp* "^guix/store/")
671 (make-regexp* "^nix/"))))
672
673(define-team core-packages
674 (team 'core-packages
675 #:name "Core packages"
676 #:description "Core packages: the GNU tool chain, Guile, Coreutils, etc."
677 #:scope (list "gnu/packages/base.scm"
678 "gnu/packages/bootstrap.scm"
679 "gnu/packages/commencement.scm"
680 "gnu/packages/cross-base.scm"
681 "gnu/packages/gcc.scm"
682 "gnu/packages/guile.scm"
683 "gnu/packages/ld-wrapper.in"
684 "gnu/packages/make-bootstrap.scm"
685 "gnu/packages/multiprecision.scm"
686 "guix/build/gnu-build-system.scm"
687 "guix/build/utils.scm"
688 "guix/build-system/gnu.scm")))
689
690(define-team debian
691 (team 'debian
692 #:name "Debian team"
693 #:description
694 "Packages related to Debian and Debian derivatives."
695 #:scope (list "gnu/packages/debian.scm")))
696
697(define-team documentation
698 (team 'documentation
699 #:name "Documentation"
700 #:description "Documentation: the manual and cookbook."
701 #:scope (list (make-regexp* "\\.texi$")
702 "doc/build.scm"
703 "gnu/system/examples/bare-bones.tmpl"
704 "gnu/system/examples/lightweight-desktop.tmpl"
705 "gnu/system/examples/desktop.tmpl")))
706
707(define-team dotnet
708 (team 'dotnet
709 #:name ".NET"
710 #:description ".NET programming environment."
711 #:scope (list "gnu/packages/dotnet.scm")))
712
713(define-team electronics
714 (team 'electronics
715 #:name "Electronics team"
716 #:description "Electronics and hardware related packages."
717 #:scope (list "gnu/packages/electronics.scm"
718 "gnu/packages/hdl.scm"
719 "gnu/packages/libftdi.scm"
720 "gnu/packages/engineering.scm"
721 "gnu/packages/flashing-tools.scm")))
722
723(define-team emacs
724 (team 'emacs
725 #:name "Emacs team"
726 #:description "The extensible, customizable text editor and its
727ecosystem."
728 #:scope (list "gnu/packages/aux-files/emacs/guix-emacs.el"
729 "gnu/packages/aux-files/emacs/comp-integrity.el"
730 (make-regexp* "^gnu/packages/emacs(-.+|)\\.scm$")
731 "gnu/packages/tree-sitter.scm"
732 "guix/build/emacs-build-system.scm"
733 "guix/build/emacs-utils.scm"
734 "guix/build-system/emacs.scm"
735 "guix/import/elpa.scm"
736 "guix/scripts/import/elpa.scm"
737 "tests/import/elpa.scm")))
738
739(define-team embedded
740 (team 'embedded
741 #:name "Embedded"
742 #:scope (list "gnu/packages/bootloaders.scm"
743 "gnu/packages/coreboot.scm"
744 "gnu/packages/embedded.scm"
745 "gnu/packages/firmware.scm")))
746
747(define-team games
748 (team 'games
749 #:name "Games and Toys"
750 #:description "Packaging programs for amusement."
751 #:scope (list "gnu/packages/emulators.scm"
752 "gnu/packages/games.scm"
753 "gnu/packages/game-development.scm"
754 "gnu/packages/luanti.scm"
755 "gnu/packages/esolangs.scm" ; granted, rather niche
756 "gnu/packages/motti.scm"
757 "gnu/services/games.scm"
758 "gnu/tests/games.scm"
759 "guix/build/luanti-build-system.scm")))
760
761(define-team gnome
762 (team 'gnome
763 #:name "Gnome team"
764 #:description
765 "The Gnome desktop environment, along with core technologies such as
766GLib/GIO, GTK, GStreamer and Webkit."
767 #:scope (list (make-regexp* "etc/teams/gnome")
768 "gnu/packages/glib.scm"
769 "gnu/packages/gstreamer.scm"
770 "gnu/packages/gtk.scm"
771 "gnu/packages/gnome.scm"
772 "gnu/packages/gnome-circle.scm"
773 "gnu/packages/gnome-xyz.scm"
774 "gnu/packages/webkit.scm"
775 "gnu/services/desktop.scm"
776 "guix/build/glib-or-gtk-build-system.scm"
777 "guix/build/meson-build-system.scm")))
778
779(define-team go
780 (team 'go
781 #:name "Go team"
782 #:scope (list "gnu/packages/configuration-management.scm"
783 (make-regexp* "gnu/packages/golang(-.+|)\\.scm$")
784 "gnu/packages/syncthing.scm"
785 "gnu/packages/terraform.scm"
786 "guix/build-system/go.scm"
787 "guix/build/go-build-system.scm"
788 "guix/import/go.scm"
789 "guix/scripts/import/go.scm"
790 "tests/import/go.scm")))
791
792(define-team guile
793 (team 'guile
794 #:name "Guile team"
795 #:description
796 "Team for the Guile platform, libraries, and build system."
797 #:scope (list "gnu/packages/guile.scm"
798 "gnu/packages/guile-wm.scm"
799 "gnu/packages/guile-xyz.scm"
800 "guix/build-system/guile.scm"
801 "guix/build/guile-build-system.scm")))
802
803(define-team hare
804 (team 'hare
805 #:name "Hare"
806 #:scope (list "gnu/packages/hare.scm"
807 "gnu/packages/hare-apps.scm"
808 "gnu/packages/hare-xyz.scm"
809 "guix/build-system/hare.scm"
810 "guix/build/hare-build-system.scm")))
811
812(define-team haskell
813 (team 'haskell
814 #:name "Haskell team"
815 #:description
816 "GHC, Hugs, Haskell packages, the \"hackage\" and \"stackage\" importers, and
817the haskell-build-system."
818 #:scope
819 (list "gnu/packages/dhall.scm"
820 ;; Match haskell.scm and haskell-*.scm.
821 (make-regexp* "^gnu/packages/haskell(-.+|)\\.scm$")
822 "gnu/packages/purescript.scm"
823 "guix/build/haskell-build-system.scm"
824 "guix/build-system/haskell.scm"
825 "guix/import/cabal.scm"
826 "guix/import/hackage.scm"
827 "guix/import/stackage.scm"
828 "guix/scripts/import/hackage.scm")))
829
830(define-team home
831 (team 'home
832 #:name "Team for \"Guix Home\""
833 #:scope (list (make-regexp* "^(gnu|guix/scripts)/home(\\.scm$|/)")
834 "tests/guix-home.sh"
835 "tests/home-import.scm"
836 "tests/home-services.scm")))
837
838(define-team hpc
839 (team 'hpc
840 #:name "High-performance computing team"
841 #:description "High-performance computing (HPC) related packages."
842 #:scope (list "gnu/packages/fabric-management.scm"
843 "gnu/packages/mpi.scm"
844 "gnu/packages/oneapi.scm"
845 "gnu/packages/opencl.scm"
846 "gnu/packages/parallel.scm"
847 "gnu/packages/rocm.scm"
848 "gnu/packages/rocm-apps.scm"
849 "gnu/packages/rocm-tools.scm"
850 "gnu/packages/rocm-libs.scm"
851 "gnu/packages/sycl.scm"
852 "gnu/packages/tbb.scm"
853 "gnu/packages/vulkan.scm")))
854
855(define-team hurd
856 (team 'hurd
857 #:name "Team for the Hurd"
858 #:description "GNU Hurd packages and operating system support."
859 #:scope (list "gnu/system/hurd.scm"
860 "gnu/system/images/hurd.scm"
861 "gnu/build/hurd-boot.scm"
862 "gnu/services/hurd.scm"
863 "gnu/packages/hurd.scm")))
864
865(define-team installer
866 (team 'installer
867 #:name "Installer script and system installer"
868 #:scope (list (make-regexp* "^gnu/installer(\\.scm$|/)"))))
869
870(define-team java
871 (team 'java
872 #:name "Java and Maven team"
873 #:description
874 "The JDK and JRE, the Maven build system, Java packages, the ant-build-system,
875and the maven-build-system."
876 #:scope
877 (list "gnu/packages/clojure.scm"
878 ;; Match java.scm and java-*.scm.
879 (make-regexp* "^gnu/packages/java(-.+|)\\.scm$")
880 ;; Match maven.scm and maven-*.scm
881 (make-regexp* "^gnu/packages/maven(-.+|)\\.scm$")
882 "gnu/packages/netbeans.scm"
883 "guix/build/ant-build-system.scm"
884 "guix/build/clojure-build-system.scm"
885 "guix/build/clojure-utils.scm"
886 "guix/build/java-utils.scm"
887 "guix/build/maven-build-system.scm"
888 ;; The maven directory
889 (make-regexp* "^guix/build/maven/")
890 "guix/build-system/ant.scm"
891 "guix/build-system/clojure.scm"
892 "guix/build-system/maven.scm")))
893
894(define-team javascript
895 (team 'javascript
896 #:name "JavaScript team"
897 #:description
898 "JavaScript/Node.js packages, the node build system."
899 #:scope (list "gnu/packages/javascript.scm"
900 "gnu/packages/node-xyz.scm"
901 "gnu/packages/node.scm"
902 "guix/build-system/node.scm"
903 "guix/build/node-build-system.scm"
904 "guix/import/npm-binary.scm"
905 "guix/scripts/import/npm-binary.scm")))
906
907(define-team julia
908 (team 'julia
909 #:name "Julia team"
910 #:description
911 "The Julia language, Julia packages, and the julia-build-system."
912 #:scope (list (make-regexp* "^gnu/packages/julia(-.+|)\\.scm$")
913 "guix/build/julia-build-system.scm"
914 "guix/build-system/julia.scm")))
915
916(define-team kde
917 (team 'kde
918 #:name "KDE team"
919 #:description
920 "The plasma desktop environment, and KDE Applications."
921 #:scope (list (make-regexp* "^gnu/packages/(kde)(-.+|)\\.scm$"))))
922
923(define-team linux-libre
924 (team 'linux-libre
925 #:name "Linux-libre kernel team"
926 #:scope (list "gnu/build/linux-modules.scm"
927 (make-regexp* "^gnu/packages/aux-files/linux-libre.*$")
928 "gnu/packages/linux.scm"
929 "gnu/tests/linux-modules.scm"
930 "guix/build/linux-module-build-system.scm"
931 "guix/build-system/linux-module.scm"
932 "etc/manifests/kernels.scm")))
933
934(define-team lisp
935 (team 'lisp
936 #:name "Lisp team"
937 #:description
938 "Common Lisp and similar languages, Common Lisp packages and the
939asdf-build-system."
940 #:scope (list (make-regexp* "^gnu/packages/lisp(-.+|)\\.scm$")
941 "guix/build/asdf-build-system.scm"
942 "guix/build/lisp-utils.scm"
943 "guix/build-system/asdf.scm")))
944
945(define-team localization
946 (team 'localization
947 #:name "Localization (l10n) team"
948 #:description
949 "Localization of your system to specific languages."
950 #:scope (list "gnu/packages/anthy.scm"
951 "gnu/packages/fcitx5.scm"
952 "gnu/packages/fonts.scm"
953 "gnu/packages/ibus.scm")))
954
955(define-team lua
956 (team 'lua
957 #:name "Lua team"
958 #:description
959 "Lua, Fennel, and related packages."
960 #:scope (list "gnu/packages/lua.scm"
961 "gnu/packages/luanti.scm")))
962
963(define-team lxqt
964 (team 'lxqt
965 #:name "LXQt team"
966 #:description "LXQt desktop environment."
967 #:scope (list "gnu/packages/lxqt.scm")))
968
969(define-team mate
970 (team 'mate
971 #:name "MATE team"
972 #:description "MATE desktop environment"
973 #:scope (list "gnu/packages/mate.scm")))
974
975(define-team mentors
976 (team 'mentors
977 #:name "Mentors"
978 #:description
979 "A group of mentors who chaperone contributions by newcomers."))
980
981(define-team mozilla
982 (team 'mozilla
983 #:name "Mozilla"
984 #:description
985 "Taking care of Icedove and Web Browsers based on Mozilla Thunderbird
986and Firefox."
987 #:scope (list "gnu/build/icecat-extension.scm"
988 "gnu/packages/browser-extensions.scm"
989 "gnu/packages/gnuzilla.scm"
990 "gnu/packages/librewolf.scm"
991 "gnu/packages/tor-browsers.scm")))
992
993(define-team ocaml
994 (team 'ocaml
995 #:name "OCaml and Dune team"
996 #:description
997 "The OCaml language, the Dune build system, OCaml packages, the \"opam\"
998importer, and the ocaml-build-system."
999 #:scope
1000 (list "gnu/packages/ocaml.scm"
1001 "gnu/packages/coq.scm"
1002 "gnu/packages/rocq.scm"
1003 "guix/build/ocaml-build-system.scm"
1004 "guix/build/dune-build-system.scm"
1005 "guix/build-system/ocaml.scm"
1006 "guix/build-system/dune.scm"
1007 "guix/import/opam.scm"
1008 "guix/scripts/import/opam.scm"
1009 "tests/import/opam.scm")))
1010
1011(define-team perl
1012 (team 'perl
1013 #:name "Perl and Raku team"
1014 #:description
1015 "Perl & Raku packages, the \"cpan\" importer, and the
1016perl-build-system as well as the rakudo-build-system."
1017 #:scope
1018 (list (make-regexp* "^gnu/packages/perl(-.+|)\\.scm$")
1019 "guix/build/perl-build-system.scm"
1020 "guix/build/rakudo-build-system.scm"
1021 "guix/build-system/perl.scm"
1022 "guix/build-system/rakudo.scm"
1023 "guix/import/cpan.scm"
1024 "guix/scripts/import/cpan.scm")))
1025
1026(define-team python
1027 (team 'python
1028 #:name "Python team"
1029 #:description
1030 "Python, Python packages, the \"pypi\" importer, and the python-build-system."
1031 #:scope
1032 (list (make-regexp* "^gnu/packages/aux-files/python/.*\\.py$")
1033 "gnu/packages/django.scm"
1034 "gnu/packages/jupyter.scm"
1035 (make-regexp* "^gnu/packages/python(-.+|)\\.scm$")
1036 "gnu/packages/sphinx.scm"
1037 "gnu/packages/tryton.scm"
1038 "guix/build-system/pyproject.scm"
1039 "guix/build-system/python.scm"
1040 "guix/build/pyproject-build-system.scm"
1041 "guix/build/python-build-system.scm"
1042 "guix/build/toml.scm" ;temporary, until other build system will use it
1043 "guix/import/pypi.scm"
1044 "guix/scripts/import/pypi.scm"
1045 "tests/import/pypi.scm"
1046 "tests/toml.scm")))
1047
1048(define-team qa-packages
1049 (team 'qa-packages
1050 #:name "Team for quality assurance packages"
1051 #:description
1052 "Quality assurance software (CI/CD, testing, analysis;
1053no direct relation to Guix's QA)."
1054 #:scope (list "gnu/packages/benchmark.scm"
1055 "gnu/packages/check.scm"
1056 "gnu/packages/ci.scm"
1057 "gnu/packages/code.scm"
1058 "gnu/packages/debug.scm"
1059 "gnu/packages/dezyne.scm"
1060 "gnu/packages/libunwind.scm"
1061 "gnu/services/ci.scm"
1062 "gnu/tests/ci.scm")))
1063
1064(define-team qt
1065 (team 'qt
1066 #:name "Qt team"
1067 #:description
1068 "The Qt toolkit/library and the qt-build-system,
1069as well as some packages using Qt."
1070 #:scope (list "gnu/packages/qt.scm"
1071 "guix/build-system/qt.scm"
1072 "guix/build/qt-build-system.scm"
1073 "guix/build/qt-utils.scm")))
1074
1075(define-team r
1076 (team 'r
1077 #:name "R team"
1078 #:description
1079 "The R language, CRAN and Bioconductor repositories, the \"cran\" importer,
1080and the r-build-system."
1081 #:scope (list "gnu/packages/bioconductor.scm"
1082 "gnu/packages/cran.scm"
1083 "guix/build/r-build-system.scm"
1084 "guix/build-system/r.scm"
1085 "guix/import/cran.scm"
1086 "guix/scripts/import/cran.scm"
1087 "tests/import/cran.scm")))
1088
1089(define-team racket
1090 (team 'racket
1091 #:name "Racket team"
1092 #:description
1093 "The Racket language and Racket-based languages, Racket packages,
1094Racket's variant of Chez Scheme, and development of a Racket build system and
1095importer."
1096 #:scope (list "gnu/packages/chez.scm"
1097 "gnu/packages/racket.scm")))
1098
1099(define-team release
1100 (team 'release
1101 #:name "Release team"
1102 #:description
1103 "The current release team. Members are expected to change with each
1104release."
1105 #:scope (list "NEWS"
1106 (make-regexp* "^etc/manifests/release-.+\\.scm$")
1107 (make-regexp* "^etc/teams/release/"))))
1108
1109(define-team reproduciblebuilds
1110 (team 'reproduciblebuilds
1111 #:name "Reproducible Builds team"
1112 #:description
1113 "Reproducible Builds tooling and issues that affect any guix packages."
1114 #:scope (list "gnu/packages/diffoscope.scm")))
1115
1116(define-team ruby
1117 (team 'ruby
1118 #:name "Ruby team"
1119 #:scope (list (make-regexp* "^gnu/packages/(ruby)(-.+|)\\.scm$")
1120 "guix/build/ruby-build-system.scm"
1121 "guix/build-system/ruby.scm"
1122 "guix/import/gem.scm"
1123 "guix/scripts/import/gem.scm"
1124 "tests/import/gem.scm")))
1125
1126(define-team rust
1127 (team 'rust
1128 #:name "Rust"
1129 #:scope (list (make-regexp* "^gnu/packages/(crates|rust)(-.+|)\\.scm$")
1130 "gnu/packages/sequoia.scm"
1131 "guix/build/cargo-build-system.scm"
1132 "guix/build/cargo-utils.scm"
1133 "guix/build-system/cargo.scm"
1134 "guix/import/crate.scm"
1135 "guix/import/crate/cargo-lock.scm"
1136 "guix/scripts/import/crate.scm"
1137 "tests/import/crate.scm")))
1138
1139(define-team crypto
1140 (team 'crypto
1141 #:name "Crypto team"
1142 #:description
1143 "Secrets, passwords, cryptography and security related packages."
1144 #:scope (list (make-regexp* "^gnu/packages/(.*-|)crypto\\.scm$")
1145 "gnu/packages/cryptsetup.scm"
1146 "gnu/packages/cybersecurity.scm"
1147 "gnu/packages/gnupg.scm"
1148 "gnu/packages/nettle.scm"
1149 "gnu/packages/password-utils.scm"
1150 "gnu/packages/security-token.scm"
1151 "gnu/packages/ssh.scm"
1152 "gnu/packages/tls.scm"
1153 "gnu/packages/vpn.scm")))
1154
1155(define-team science
1156 (team 'science
1157 #:name "Science team"
1158 #:description "The main science disciplines and fields related
1159packages (e.g. Astronomy, Chemistry, Math, Physics etc.)"
1160 #:scope (list (make-regexp* "^gnu/packages/fortran(-.+|)\\.scm$")
1161 "gnu/packages/algebra.scm"
1162 "gnu/packages/astronomy.scm"
1163 "gnu/packages/chemistry.scm"
1164 "gnu/packages/geo.scm"
1165 "gnu/packages/graph.scm"
1166 "gnu/packages/lean.scm"
1167 "gnu/packages/maths.scm"
1168 "gnu/packages/medical.scm"
1169 "gnu/packages/physics.scm"
1170 "gnu/packages/sagemath.scm"
1171 "gnu/packages/statistics.scm")))
1172
1173(define-team security-response
1174 (team 'security-response
1175 #:name "Guix security response team"
1176 #:description "Security response team: \
1177https://guix.gnu.org/security/ ."))
1178
1179(define-team sugar
1180 (team 'sugar
1181 #:name "Sugar team"
1182 #:description
1183 "Everything related to the Sugar Desktop and learning environment."
1184 #:scope (list "gnu/packages/sugar.scm")))
1185
1186(define-team sysadmin
1187 (team 'sysadmin
1188 #:name "Sysadmin team"
1189 #:description
1190 "Networking, server clustering, high availability."
1191 #:scope (list "gnu/packages/admin.scm"
1192 "gnu/packages/acl.scm"
1193 "gnu/packages/adns.scm"
1194 "gnu/packages/antivirus.scm"
1195 "gnu/packages/apparmor.scm"
1196 "gnu/packages/authentication.scm"
1197 "gnu/packages/cluster.scm"
1198 "gnu/packages/configuration-management.scm"
1199 "gnu/packages/databases.scm"
1200 "gnu/packages/distributed.scm"
1201 "gnu/packages/dns.scm"
1202 "gnu/packages/high-availability.scm"
1203 "gnu/packages/kerberos.scm"
1204 "gnu/packages/logging.scm"
1205 "gnu/packages/monitoring.scm"
1206 "gnu/packages/nfs.scm"
1207 "gnu/packages/openldap.scm"
1208 "gnu/packages/openstack.scm"
1209 "gnu/packages/prometheus.scm"
1210 "gnu/packages/rdesktop.scm"
1211 "gnu/packages/samba.scm"
1212 "gnu/packages/selinux.scm"
1213 "gnu/packages/storage.scm"
1214 "gnu/packages/task-runners.scm"
1215 "gnu/packages/terraform.scm"
1216 "gnu/packages/virtualization.scm"
1217 "gnu/packages/vnc.scm"
1218 "gnu/services/admin.scm"
1219 "gnu/services/authentication.scm"
1220 "gnu/services/databases.scm"
1221 "gnu/services/dns.scm"
1222 "gnu/services/high-availability.scm"
1223 "gnu/services/kerberos.scm"
1224 "gnu/services/monitoring.scm"
1225 "gnu/services/nfs.scm"
1226 "gnu/services/samba.scm"
1227 "gnu/services/virtualization.scm"
1228 "gnu/services/vnc.scm"
1229 "gnu/tests/databases.scm"
1230 "gnu/tests/dns.scm"
1231 "gnu/tests/high-availability.scm"
1232 "gnu/tests/monitoring.scm"
1233 "gnu/tests/nfs.scm"
1234 "gnu/tests/samba.scm"
1235 "gnu/tests/virtualization.scm"
1236 "gnu/tests/vnc.scm")))
1237
1238(define-team telephony
1239 (team 'telephony
1240 #:name "Telephony team"
1241 #:description
1242 "Telephony packages and services such as Jami, Linphone, etc."
1243 #:scope (list "gnu/build/jami-service.scm"
1244 "gnu/packages/jami.scm"
1245 "gnu/packages/linphone.scm"
1246 "gnu/packages/telephony.scm"
1247 "gnu/services/telephony.scm"
1248 "gnu/tests/data/jami-dummy-account.dat"
1249 "gnu/tests/telephony.scm"
1250 "tests/services/telephony.scm")))
1251
1252(define-team tex
1253 (team 'tex
1254 #:name "TeX team"
1255 #:description
1256 "TeX, LaTeX, XeLaTeX, LuaTeX, TeXLive, the texlive-build-system, and
1257the \"texlive\" importer."
1258 #:scope (list "gnu/packages/tex.scm"
1259 "gnu/packages/texlive.scm"
1260 "guix/build/texlive-build-system.scm"
1261 "guix/build-system/texlive.scm"
1262 "guix/import/texlive.scm"
1263 "guix/scripts/import/texlive.scm"
1264 "tests/import/texlive.scm")))
1265
1266(define-team translations
1267 (team 'translations
1268 #:name "Translations"
1269 #:scope (list "etc/news.scm"
1270 (make-regexp* "^po/"))))
1271
1272(define-team vcs
1273 (team 'vcs
1274 #:name "Version control team"
1275 #:description
1276 "Version control packages, services, and Guix download backends."
1277 #:scope (list "gnu/packages/version-control.scm"
1278 "gnu/services/version-control.scm"
1279 "gnu/tests/version-control.scm"
1280 "guix/build/bzr.scm"
1281 "guix/build/cvs.scm"
1282 "guix/build/fossil.scm"
1283 "guix/build/git.scm"
1284 "guix/build/hg.scm"
1285 "guix/build/svn.scm")))
1286
1287(define-team xfce
1288 (team 'xfce
1289 #:name "Xfce team"
1290 #:description "Xfce desktop environment."
1291 #:scope (list "gnu/packages/xfce.scm")))
1292
1293(define-team zig
1294 (team 'zig
1295 #:name "Zig team"
1296 #:description "Zig, Zig packages, and the zig-build system"
1297 #:scope (list "gnu/packages/zig.scm"
1298 "gnu/packages/zig-xyz.scm"
1299 "guix/build/zig-build-system.scm"
1300 "guix/build-system/zig.scm")))
1301
1302
1303(define-member (person "Anderson Torres"
1304 "[email protected]"
1305 "AndersonTorres")
1306 community translations)
1307
1308(define-member (person "Eric Bavier"
1309 "[email protected]"
1310 "bavier")
1311 science)
1312
1313(define-member (person "Jonathan Brielmaier"
1314 "[email protected]"
1315 "jonsger")
1316 mozilla)
1317
1318(define-member (person "Denis Carikli"
1319 "[email protected]"
1320 "GNUtoo")
1321 embedded)
1322
1323(define-member (person "Ludovic Courtès"
1324 "[email protected]"
1325 "civodul")
1326 codeberg core core-packages guile hpc installer)
1327
1328(define-member (person "Andreas Enge"
1329 "[email protected]"
1330 "enge")
1331 bootstrap c++ codeberg core-packages crypto lxqt science tex)
1332
1333(define-member (person "Tanguy Le Carrour"
1334 "[email protected]"
1335 "tanguybl")
1336 python home release)
1337
1338(define-member (person "Tobias Geerinckx-Rice"
1339 "[email protected]"
1340 "nckx")
1341 maintainers codeberg mentors)
1342
1343(define-member (person "Steve George"
1344 "[email protected]"
1345 "futurile")
1346 codeberg rust)
1347
1348(define-member (person "Leo Famulari"
1349 "[email protected]"
1350 "lfam")
1351 codeberg linux-libre)
1352
1353(define-member (person "Efraim Flashner"
1354 "[email protected]"
1355 "efraim")
1356 maintainers codeberg embedded bootstrap rust)
1357
1358(define-member (person "jgart"
1359 "[email protected]"
1360 "jgart")
1361 hare lisp mentors)
1362
1363(define-member (person "John Kehayias"
1364 "[email protected]"
1365 "podiki")
1366 security-response)
1367
1368(define-member (person "Guillaume Le Vaillant"
1369 "[email protected]"
1370 "glv")
1371 lisp)
1372
1373(define-member (person "Julien Lepiller"
1374 "[email protected]"
1375 "roptat")
1376 java ocaml translations)
1377
1378(define-member (person "Philip McGrath"
1379 "[email protected]"
1380 "LiberalArtist")
1381 racket)
1382
1383(define-member (person "Mathieu Othacehe"
1384 "[email protected]"
1385 "mothacehe")
1386 maintainers codeberg installer mentors)
1387
1388(define-member (person "Florian Pelz"
1389 "[email protected]"
1390 "pelzflorian")
1391 translations)
1392
1393(define-member (person "Liliana Marie Prikler"
1394 "[email protected]"
1395 "lilyp")
1396 emacs games gnome qa-packages)
1397
1398(define-member (person "Ricardo Wurmus"
1399 "[email protected]"
1400 "rekado")
1401 bioinformatics codeberg r sugar)
1402
1403(define-member (person "Christopher Baines"
1404 "[email protected]"
1405 "cbaines")
1406 codeberg core mentors ruby)
1407
1408(define-member (person "Andrew Tropin"
1409 "[email protected]"
1410 "abcdw")
1411 home emacs)
1412
1413(define-member (person "Trevor Richards"
1414 "[email protected]"
1415 "trevdev")
1416 emacs lisp)
1417
1418(define-member (person "pukkamustard"
1419 "[email protected]"
1420 "pukkamustard")
1421 ocaml)
1422
1423(define-member (person "Josselin Poiret"
1424 "[email protected]"
1425 "jpoiret")
1426 installer)
1427
1428(define-member (person "Simon Tournier"
1429 "[email protected]"
1430 "zimoun")
1431 julia core mentors r security-response)
1432
1433(define-member (person "宋文武"
1434 "[email protected]"
1435 "iyzsong")
1436 games localization lxqt qt xfce)
1437
1438(define-member (person "Vagrant Cascadian"
1439 "[email protected]"
1440 "vagrantc")
1441 debian embedded linux-libre)
1442
1443(define-member (person "Vagrant Cascadian" ;XXX: duplicate
1444 "[email protected]"
1445 "vagrantc")
1446 reproduciblebuilds)
1447
1448(define-member (person "Maxim Cournoyer"
1449 "[email protected]"
1450 "apteryx")
1451 maintainers codeberg core documentation electronics javascript gnome
1452 qt telephony)
1453
1454(define-member (person "Munyoki Kilyungi"
1455 "[email protected]"
1456 "BonfaceKilz")
1457 python guile)
1458
1459(define-member (person "Gabriel Wicki"
1460 "[email protected]"
1461 "gabber")
1462 audio community documentation electronics embedded)
1463
1464(define-member (person "Divya Ranjan Pattanaik"
1465 "[email protected]"
1466 "divyaranjan")
1467 emacs rust haskell)
1468
1469(define-member (person "Clément Lassieur"
1470 "[email protected]"
1471 "snape")
1472 mozilla)
1473
1474(define-member (person "Sharlatan Hellseher"
1475 "[email protected]"
1476 "Hellseher")
1477 bioinformatics go python science zig)
1478
1479(define-member (person "Arthur Rodrigues"
1480 "[email protected]"
1481 "arthurhdrodrigues")
1482 go zig)
1483
1484(define-member (person "Mark H Weaver"
1485 "[email protected]"
1486 "mhw")
1487 mozilla)
1488
1489(define-member (person "Laurent Gatto"
1490 "[email protected]"
1491 "lgatto")
1492 r bioinformatics)
1493
1494(define-member (person "Nicolas Goaziou"
1495 "[email protected]"
1496 "ngz")
1497 tex)
1498
1499(define-member (person "André Batista"
1500 "[email protected]"
1501 "madage")
1502 mozilla)
1503
1504(define-member (person "Janneke Nieuwenhuizen"
1505 "[email protected]"
1506 "janneke")
1507 bootstrap build-tools codeberg core-packages home hurd installer
1508 qa-packages)
1509
1510(define-member (person "Zheng Junjie"
1511 "[email protected]"
1512 "Z572")
1513 core-packages)
1514
1515(define-member (person "Sughosha"
1516 "[email protected]"
1517 "SameExpert")
1518 audio kde)
1519
1520(define-member (person "Jelle Licht"
1521 "[email protected]"
1522 "jlicht")
1523 javascript release)
1524
1525(define-member (person "Cayetano Santos"
1526 "[email protected]"
1527 "csantosb")
1528 ai emacs electronics hpc crypto reproduciblebuilds)
1529
1530(define-member (person "Greg Hogan"
1531 "[email protected]"
1532 "greghogan")
1533 c++)
1534
1535(define-member (person "Hilton Chain"
1536 "[email protected]"
1537 "hako"))
1538
1539(define-member (person "Noé Lopez"
1540 "[email protected]"
1541 "Baleine")
1542 gnome release)
1543
1544(define-member (person "Ashvith Shetty"
1545 "[email protected]"
1546 "Ashvith")
1547 javascript xfce)
1548
1549(define-member (person "Konrad Hinsen"
1550 "[email protected]"
1551 "khinsen")
1552 lisp)
1553
1554(define-member (person "Vinicius Monego"
1555 "[email protected]"
1556 "monego")
1557 python science)
1558
1559(define-member (person "Yelninei"
1560 "[email protected]"
1561 "Yelninei")
1562 hurd)
1563
1564(define-member (person "Giacomo Leidi"
1565 "[email protected]"
1566 "fishinthecalculator")
1567 audio beam)
1568
1569(define-member (person "Sören Tempel"
1570 "[email protected]"
1571 "nmeum")
1572 haskell)
1573
1574(define-member (person "Saku Laesvuori"
1575 "[email protected]"
1576 "slaesvuo")
1577 haskell)
1578
1579(define-member (person "Rodion Goritskov"
1580 "[email protected]"
1581 "rodion-goritskov")
1582 games java kde linux-libre)
1583
1584(define-member (person "Jason Conroy"
1585 "[email protected]"
1586 "conroj")
1587 ocaml)
1588
1589(define-member (person "Rutherther"
1590 "[email protected]"
1591 "Rutherther")
1592 core release)
1593
1594(define-member (person "Morgan Arnold"
1595 "[email protected]"
1596 "mra")
1597 core)
1598
1599(define-member (person "Danny Milosavljevic"
1600 "[email protected]"
1601 "daym")
1602 bootstrap dotnet hpc python rust science)
1603
1604(define-member (person "Andy Tai"
1605 "[email protected]"
1606 "atai")
1607 ai)
1608
1609(define-member (person "Pierre-Henry Fröhring"
1610 "[email protected]"
1611 "phfrohring")
1612 beam)
1613
1614(define-member (person "Nguyễn Gia Phong"
1615 "[email protected]"
1616 "cnx")
1617 build-tools lua qa-packages sysadmin vcs)
1618
1619(define-member (person "Lilah Tascheter"
1620 "[email protected]"
1621 "tinystar")
1622 hare)
1623
1624(define-member (person "FuncProgLinux"
1625 "[email protected]"
1626 "FuncProgLinux")
1627 mate)
1628
1629(define-member (person "Reza Housseini"
1630 "[email protected]"
1631 "rhou")
1632 python science c++)
1633
1634(define-member (person "Yunqi Shao"
1635 "[email protected]"
1636 "yqshao")
1637 sysadmin)
1638
1639(define-member (person "Collin Doering"
1640 "[email protected]"
1641 "rekahsoft")
1642 embedded electronics haskell sysadmin)
1643
1644(define-member (person "Mathieu Lirzin"
1645 "[email protected]"
1646 "mthl")
1647 java)
1648
1649(define-member (person "Hugo Buddelmeijer"
1650 "[email protected]"
1651 "hugobuddel")
1652 python security-response)
1653
1654(define-member (person "Yan Abu Arab"
1655 "[email protected]"
1656 "tux1c")
1657 python sysadmin)
1658
1659(define-member (person "Wilko Meyer"
1660 "[email protected]"
1661 "theesm")
1662 linux-libre perl)
1663
1664(define-member (person "Untrusem"
1665 "[email protected]"
1666 "untrusem")
1667 community mozilla)
1668
1669(define-member (person "David Thompson"
1670 "[email protected]"
1671 "flockofbirbs")
1672 guile)
1673
1674(define-member (person "Sergio Pastor Pérez"
1675 "[email protected]"
1676 "pastor")
1677 guile hpc kde)
1678
1679(define-member (person "Carlo Zancanaro"
1680 "[email protected]"
1681 "czan")
1682 lua ruby)
1683
1684(define-member (person "Folât Pjêrsômêj"
1685 "[email protected]"
1686 "folaht")
1687 documentation)
1688
1689(define-member (person "Ashish SHUKLA"
1690 "[email protected]"
1691 "group")
1692 vcs)
1693
1694(define-member (person "Spencer King"
1695 "[email protected]"
1696 "spencerking")
1697 julia)
1698
1699(define-member (person "Peter Polidoro"
1700 "[email protected]"
1701 "peterpolidoro")
1702 electronics)
1703
1704(define-member (person "Thomas Kramer"
1705 "[email protected]"
1706 "tok")
1707 electronics)
1708
1709(define-member (person "gemmaro"
1710 "[email protected]"
1711 "gemmaro")
1712 ruby)
1713
1714(define-member (person "bdunahu"
1715 "[email protected]"
1716 "bdunahu")
1717 games)
1718
1719(define-member (person "Nomike"
1720 "[email protected]"
1721 "nomike")
1722 dotnet)
1723
1724(define-member (person "Fabio Natali"
1725 "[email protected]"
1726 "fnat")
1727 emacs)
1728
1729(define-member
1730 (person "Arun Isaac"
1731 "[email protected]"
1732 "arunisaac")
1733 codeberg)
1734
1735(define-member (person "Florian Korbacher"
1736 "[email protected]"
1737 "SilverlightningY")
1738 audio)
1739
1740(define-member (person "Orahcio Felício de Sousa"
1741 "[email protected]"
1742 "orahcio")
1743 go python science)
1744
1745(define-member (person "Vivien Kraus"
1746 "[email protected]"
1747 "vivien")
1748 hpc)
1749
1750(define-member (person "Ghislain Vaillant"
1751 "[email protected]"
1752 "ghisvail")
1753 bioinformatics python science)
1754
1755(define-member (person "Dan Littlewood"
1756 "[email protected]"
1757 "danielittlewood")
1758 release)
1759
1760
1761(define (find-team name)
1762 (or (hash-ref %teams (string->symbol name))
1763 (error (format #false
1764 "no such team: ~a~%" name))))
1765
1766(define (find-team-by-scope files)
1767 "Return the team(s) which scope matches at least one of the FILES, as list
1768of file names as string."
1769 (hash-fold
1770 (lambda (key team acc)
1771 (if (any (lambda (file)
1772 (any (match-lambda
1773 ((? string? scope)
1774 (string=? scope file))
1775 ((? regexp*? scope)
1776 (regexp*-exec scope file)))
1777 (team-scope team)))
1778 files)
1779 (cons team acc)
1780 acc))
1781 '()
1782 %teams))
1783
1784(define (cc . teams)
1785 "Return arguments for `git send-email' to notify the members of the given
1786TEAMS when a patch is received by Debbugs."
1787 (let ((members (append-map team-members teams)))
1788 (unless (null? members)
1789 (format #true "--add-header=\"X-Debbugs-Cc: ~{~a~^, ~}\""
1790 (map person-email (sort-members members))))))
1791
1792(define (sort-members members)
1793 "Deduplicate and sort MEMBERS alphabetically by their name."
1794 (sort (delete-duplicates members equal?)
1795 (lambda (m1 m2)
1796 (string<? (person-name m1) (person-name m2)))))
1797
1798(define (member->string member)
1799 "Return the 'email <name>' string representation of MEMBER."
1800 (let* ((name (person-name member))
1801 (quoted-name/maybe (if (string-contains name ",")
1802 (string-append "\"" name "\"")
1803 name)))
1804 (format #false "~a <~a>" quoted-name/maybe (person-email member))))
1805
1806(define* (list-members team #:key (prefix ""))
1807 "Print the members of the given TEAM."
1808 (for-each (lambda (member)
1809 (format #t "~a~a~%" prefix (member->string member)))
1810 (sort-members (team-members team))))
1811
1812(define (print-team team)
1813 "Print TEAM, a <team> record object."
1814 (format #t
1815 "\
1816id: ~a
1817name: ~a
1818description: ~a
1819~amembers:
1820"
1821 (team-id team)
1822 (team-name team)
1823 (or (and=> (team-description team)
1824 (lambda (text)
1825 (string->recutils
1826 (fill-paragraph text (%text-width)
1827 (string-length "description: ")))))
1828 "<none>")
1829 (match (team-scope team)
1830 (() "")
1831 (scope (format #f "scope:~%~{+ ~a~^~%~}~%"
1832 (sort (map (match-lambda
1833 ((? regexp*? rx)
1834 (regexp*-pattern rx))
1835 (item item))
1836 scope)
1837 string<?)))))
1838 (list-members team #:prefix "+ ")
1839 (newline))
1840
1841(define (sort-teams teams)
1842 "Sort TEAMS, a list of <team> record objects."
1843 (sort teams
1844 (lambda (team1 team2)
1845 (string<? (symbol->string (team-id team1))
1846 (symbol->string (team-id team2))))))
1847
1848(define* (list-teams #:optional team-names)
1849 "Print all teams, their scope and their members."
1850 (for-each print-team
1851 (sort-teams
1852 (if team-names
1853 (map find-team team-names)
1854 (hash-map->list (lambda (_ value) value) %teams)))))
1855
1856
1857(define (diff-revisions rev-start rev-end)
1858 "Return the list of added, modified or removed files between REV-START
1859and REV-END, two git revision strings."
1860 (let* ((repository (repository-open (getcwd)))
1861 (commit1 (commit-lookup repository
1862 (object-id
1863 (revparse-single repository rev-start))))
1864 (commit2 (commit-lookup repository
1865 (object-id
1866 (revparse-single repository rev-end))))
1867 (diff (diff-tree-to-tree repository
1868 (commit-tree commit1)
1869 (commit-tree commit2)))
1870 (files '()))
1871 (diff-foreach
1872 diff
1873 (lambda (delta progress)
1874 (set! files
1875 (cons (diff-file-path (diff-delta-old-file delta)) files))
1876 0)
1877 (const 0)
1878 (const 0)
1879 (const 0))
1880 files))
1881
1882(define (git-patch->commit-id file)
1883 "Parse the commit ID from FILE, a patch produced with git."
1884 (call-with-input-file file
1885 (lambda (port)
1886 (let loop ((line (read-line port)))
1887 (when (eof-object? line)
1888 (error "could not find 'from' commit in patch" file))
1889 (let ((m (string-match "^From ([0-9a-f]{40})" line)))
1890 (if m
1891 (match:substring m 1)
1892 (loop (read-line port))))))))
1893
1894(define (git-patch->revisions file)
1895 "Return the start and end revisions of FILE, a patch file produced with git."
1896 (let* ((rev-end (git-patch->commit-id file))
1897 (rev-start (string-append rev-end "^")))
1898 (list rev-start rev-end)))
1899
1900(define (patch->teams patch-file)
1901 "Return the name of the teams in scope for the changes in PATCH-FILE."
1902 (map (compose symbol->string team-id)
1903 (find-team-by-scope (apply diff-revisions
1904 (git-patch->revisions patch-file)))))
1905
1906(define (team-id->forgejo-id id)
1907 "Return a name (string) suitable as a Forgejo team name."
1908 (define valid ;"AlphaDashDot"
1909 (char-set-union char-set:ascii (char-set #\-) (char-set #\.)))
1910
1911 (define (valid? chr)
1912 (char-set-contains? valid chr))
1913
1914 (string-map (match-lambda
1915 (#\+ #\p) ;special case for "c++"
1916 ((? valid? chr) chr)
1917 (_ #\-))
1918 (symbol->string id)))
1919
1920(define (team->codeowners-snippet team)
1921 (string-join (map (lambda (scope)
1922 (format #f "~50a @guix/~a"
1923 (if (regexp*? scope)
1924 (let ((regexp (regexp*-pattern scope)))
1925 ;; Caret may not match as expected in
1926 ;; 'CODEOWNERS' so drop it.
1927 (if (string-prefix? "^" regexp)
1928 (string-drop regexp 1)
1929 regexp))
1930 (regexp-quote scope))
1931 (team-id->forgejo-id (team-id team))))
1932 (team-scope team))
1933 "\n"
1934 'suffix))
1935
1936(define (export-codeowners port)
1937 (let ((teams (sort-teams
1938 (hash-map->list (lambda (_ value) value) %teams))))
1939 (display "\
1940# This -*- conf -*- file was generated by './etc/teams.scm codeowners'.
1941#
1942# It describes the expected reviewers for a pull request based on the
1943# changed files. Unlike what the name of the file suggests they don't
1944# own the code (ownership is collective in this house!) but merely have
1945# a good understanding of that area of the codebase and therefore are
1946# usually suited as a reviewer.\n\n"
1947 port)
1948 (for-each (lambda (team)
1949 (let ((scope (team->codeowners-snippet team)))
1950 ;; Some teams, like Mentors and Community have no scope,
1951 ;; which would result in seemingly arbitrary newlines.
1952 (unless (string-null? scope)
1953 (display scope port)
1954 (newline port))))
1955 teams)))
1956
1957
1958(define (main . args)
1959 (match args
1960 (("cc" . team-names)
1961 (apply cc (map find-team team-names)))
1962 (("cc-all-team-members")
1963 (apply cc (hash-map->list (lambda (_ team) team) %teams)))
1964 (("cc-members" patch-file)
1965 (unless (file-exists? patch-file)
1966 (error "patch file does not exist:" patch-file))
1967 (apply main "cc-members" (git-patch->revisions patch-file)))
1968 (("cc-members" rev-start rev-end)
1969 (apply cc (find-team-by-scope
1970 (diff-revisions rev-start rev-end))))
1971 (("cc-members-header-cmd" patch-file)
1972 (let* ((teams (map find-team (patch->teams patch-file)))
1973 (members (sort-members (append-map team-members teams))))
1974 (unless (null? members)
1975 (format #true "X-Debbugs-Cc: ~{~a~^, ~}"
1976 (map member->string members)))))
1977 (("cc-mentors-header-cmd" patch-file)
1978 (format #true "X-Debbugs-Cc: ~{~a~^, ~}"
1979 (map member->string
1980 (sort-members (team-members (find-team "mentors"))))))
1981 (("get-maintainer" patch-file)
1982 (apply main "list-members" (patch->teams patch-file)))
1983 (("list-teams" . args)
1984 (list-teams))
1985 (("list-members" . team-names)
1986 (for-each
1987 (lambda (team-name)
1988 (list-members (find-team team-name)))
1989 team-names))
1990 (("show" . team-names)
1991 (list-teams team-names))
1992 (("codeowners")
1993 (export-codeowners (current-output-port)))
1994 (("sync-codeberg-teams" token)
1995 (synchronize-teams token))
1996 (anything
1997 (format (current-error-port)
1998 "Usage: etc/teams.scm <command> [<args>]
1999
2000Commands:
2001 cc <team-name>
2002 get git send-email flags for cc-ing <team-name>
2003 cc-members <start> <end> | <patch>
2004 cc teams related to files changed between revisions or in a patch file
2005 cc-all-team-members
2006 cc all members of all teams (useful in GCD processes)
2007 cc-members-header-cmd <patch>
2008 cc-members variant for use with 'git send-email --header-cmd'
2009 cc-mentors-header-cmd <patch>
2010 command to use with 'git send-email --header-cmd' to notify mentors
2011 list-teams
2012 list teams and their members
2013 list-members <team-name>
2014 list members belonging to <team-name>
2015 get-maintainer <patch>
2016 compatibility mode with Linux get_maintainer.pl
2017 show <team-name>
2018 display <team-name> properties
2019 codeowners
2020 write a 'CODEOWNERS' file suitable for Codeberg on standard output
2021 sync-codeberg-teams <token>
2022 create or update the list of teams at Codeberg~%"))))
2023
2024(apply main (cdr (command-line)))