teams.scm.in 19 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606
  1. #!@GUILE@ \
  2. --no-auto-compile -s
  3. !#
  4. ;;; GNU Guix --- Functional package management for GNU
  5. ;;; Copyright © 2022 Ricardo Wurmus <rekado@elephly.net>
  6. ;;; Copyright © 2022 Mathieu Othacehe <othacehe@gnu.org>
  7. ;;;
  8. ;;; This file is part of GNU Guix.
  9. ;;;
  10. ;;; GNU Guix is free software; you can redistribute it and/or modify it
  11. ;;; under the terms of the GNU General Public License as published by
  12. ;;; the Free Software Foundation; either version 3 of the License, or (at
  13. ;;; your option) any later version.
  14. ;;;
  15. ;;; GNU Guix is distributed in the hope that it will be useful, but
  16. ;;; WITHOUT ANY WARRANTY; without even the implied warranty of
  17. ;;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  18. ;;; GNU General Public License for more details.
  19. ;;;
  20. ;;; You should have received a copy of the GNU General Public License
  21. ;;; along with GNU Guix. If not, see <http://www.gnu.org/licenses/>.
  22. ;;; Commentary:
  23. ;; This code defines development teams and team members, as well as their
  24. ;; scope.
  25. ;;; Code:
  26. (use-modules (srfi srfi-1)
  27. (srfi srfi-9)
  28. (srfi srfi-26)
  29. (ice-9 format)
  30. (ice-9 regex)
  31. (ice-9 match)
  32. (guix ui)
  33. (git))
  34. (define-record-type <team>
  35. (make-team id name description members scope)
  36. team?
  37. (id team-id)
  38. (name team-name)
  39. (description team-description)
  40. (members team-members set-team-members!)
  41. (scope team-scope))
  42. (define-record-type <person>
  43. (make-person name email)
  44. person?
  45. (name person-name)
  46. (email person-email))
  47. (define* (person name #:optional email)
  48. (make-person name email))
  49. (define* (team id #:key name description (members '())
  50. (scope '()))
  51. (make-team id
  52. (or name (symbol->string id))
  53. description
  54. members
  55. scope))
  56. (define %teams
  57. (make-hash-table))
  58. (define-syntax define-team
  59. (lambda (x)
  60. (syntax-case x ()
  61. ((_ id value)
  62. #`(begin
  63. (define-public id value)
  64. (hash-set! %teams 'id id))))))
  65. (define-syntax-rule (define-member person teams ...)
  66. (let ((p person))
  67. (for-each (lambda (team-id)
  68. (let ((team
  69. (hash-ref %teams team-id
  70. (lambda ()
  71. (error (format #false
  72. "Unknown team ~a for ~a~%"
  73. team-id p))))))
  74. (set-team-members!
  75. team (cons p (team-members team)))))
  76. (quote (teams ...)))))
  77. (define-team python
  78. (team 'python
  79. #:name "Python team"
  80. #:description
  81. "Python, Python packages, the \"pypi\" importer, and the python-build-system."
  82. #:scope
  83. (list "gnu/packages/django.scm"
  84. "gnu/packages/jupyter.scm"
  85. ;; Match haskell.scm and haskell-*.scm.
  86. (make-regexp "^gnu/packages/python(-.+|)\\.scm$")
  87. "gnu/packages/sphinx.scm"
  88. "gnu/packages/tryton.scm"
  89. "guix/build/python-build-system.scm"
  90. "guix/build-system/python.scm"
  91. "guix/import/pypi.scm"
  92. "guix/scripts/import/pypi.scm"
  93. "tests/pypi.scm")))
  94. (define-team haskell
  95. (team 'haskell
  96. #:name "Haskell team"
  97. #:description
  98. "GHC, Hugs, Haskell packages, the \"hackage\" and \"stackage\" importers, and
  99. the haskell-build-system."
  100. #:scope
  101. (list "gnu/packages/dhall.scm"
  102. ;; Match haskell.scm and haskell-*.scm.
  103. (make-regexp "^gnu/packages/haskell(-.+|)\\.scm$")
  104. "gnu/packages/purescript.scm"
  105. "guix/build/haskell-build-system.scm"
  106. "guix/build-system/haskell.scm"
  107. "guix/import/cabal.scm"
  108. "guix/import/hackage.scm"
  109. "guix/import/stackage.scm"
  110. "guix/scripts/import/hackage.scm")))
  111. (define-team r
  112. (team 'r
  113. #:name "R team"
  114. #:description
  115. "The R language, CRAN and Bioconductor repositories, the \"cran\" importer,
  116. and the r-build-system."
  117. #:scope (list "gnu/packages/bioconductor.scm"
  118. "gnu/packages/cran.scm"
  119. "guix/build/r-build-system.scm"
  120. "guix/build-system/r.scm"
  121. "guix/import/cran.scm"
  122. "guix/scripts/import/cran.scm"
  123. "tests/cran.scm")))
  124. (define-team julia
  125. (team 'julia
  126. #:name "Julia team"
  127. #:description
  128. "The Julia language, Julia packages, and the julia-build-system."
  129. #:scope (list (make-regexp "^gnu/packages/julia(-.+|)\\.scm$")
  130. "guix/build/julia-build-system.scm"
  131. "guix/build-system/julia.scm")))
  132. (define-team ocaml
  133. (team 'ocaml
  134. #:name "OCaml and Dune team"
  135. #:description
  136. "The OCaml language, the Dune build system, OCaml packages, the \"opam\"
  137. importer, and the ocaml-build-system."
  138. #:scope
  139. (list "gnu/packages/ocaml.scm"
  140. "gnu/packages/coq.scm"
  141. "guix/build/ocaml-build-system.scm"
  142. "guix/build/dune-build-system.scm"
  143. "guix/build-system/ocaml.scm"
  144. "guix/build-system/dune.scm"
  145. "guix/import/opam.scm"
  146. "guix/scripts/import/opam.scm"
  147. "tests/opam.scm")))
  148. (define-team java
  149. (team 'java
  150. #:name "Java and Maven team"
  151. #:description
  152. "The JDK and JRE, the Maven build system, Java packages, the ant-build-system,
  153. and the maven-build-system."
  154. #:scope
  155. (list ;; Match java.scm and java-*.scm.
  156. (make-regexp "^gnu/packages/java(-.+|)\\.scm$")
  157. ;; Match maven.scm and maven-*.scm
  158. (make-regexp "^gnu/packages/maven(-.+|)\\.scm$")
  159. "guix/build/ant-build-system.scm"
  160. "guix/build/java-utils.scm"
  161. "guix/build/maven-build-system.scm"
  162. ;; The maven directory
  163. (make-regexp "^guix/build/maven/")
  164. "guix/build-system/ant.scm"
  165. "guix/build-system/maven.scm")))
  166. (define-team science
  167. (team 'science
  168. #:name "Science team"))
  169. (define-team emacs
  170. (team 'emacs
  171. #:name "Emacs team"
  172. #:description "The extensible, customizable text editor and its
  173. ecosystem."
  174. #:scope (list (make-regexp "^gnu/packages/emacs(-.+|)\\.scm$")
  175. "guix/build/emacs-build-system.scm"
  176. "guix/build/emacs-utils.scm"
  177. "guix/build-system/emacs.scm"
  178. "guix/import/elpa.scm"
  179. "guix/scripts/import/elpa.scm"
  180. "tests/elpa.scm")))
  181. (define-team lisp
  182. (team 'lisp
  183. #:name "Lisp team"
  184. #:description
  185. "Common Lisp and similar languages, Common Lisp packages and the
  186. asdf-build-system."
  187. #:scope (list (make-regexp "^gnu/packages/lisp(-.+|)\\.scm$")
  188. "guix/build/asdf-build-system.scm"
  189. "guix/build/lisp-utils.scm"
  190. "guix/build-system/asdf.scm")))
  191. (define-team ruby
  192. (team 'ruby
  193. #:name "Ruby team"
  194. #:scope (list "gnu/packages/ruby.scm"
  195. "guix/build/ruby-build-system.scm"
  196. "guix/build-system/ruby.scm"
  197. "guix/import/gem.scm"
  198. "guix/scripts/import/gem.scm"
  199. "tests/gem.scm")))
  200. (define-team go
  201. (team 'go
  202. #:name "Go team"
  203. #:scope (list "gnu/packages/golang.scm"
  204. "guix/build/go-build-system.scm"
  205. "guix/build-system/go.scm"
  206. "guix/import/go.scm"
  207. "guix/scripts/import/go.scm"
  208. "tests/go.scm")))
  209. (define-team embedded-bootstrap
  210. (team 'embedded-bootstrap
  211. #:name "Embedded / Bootstrap"))
  212. (define-team rust
  213. (team 'rust
  214. #:name "Rust"
  215. #:scope (list (make-regexp "^gnu/packages/(crates|rust)(-.+|)\\.scm$")
  216. "guix/build/cargo-build-system.scm"
  217. "guix/build/cargo-utils.scm"
  218. "guix/build-system/cargo.scm"
  219. "guix/import/crate.scm"
  220. "guix/scripts/import/crate.scm"
  221. "tests/crate.scm")))
  222. (define-team kernel
  223. (team 'kernel
  224. #:name "Linux-libre kernel team"
  225. #:scope (list "gnu/build/linux-modules.scm"
  226. "gnu/packages/linux.scm"
  227. "gnu/tests/linux-modules.scm"
  228. "guix/build/linux-module-build-system.scm"
  229. "guix/build-system/linux-module.scm")))
  230. (define-team core
  231. (team 'core
  232. #:name "Core / Tools / Internals"
  233. #:scope
  234. (list "guix/avahi.scm"
  235. "guix/base16.scm"
  236. "guix/base32.scm"
  237. "guix/base64.scm"
  238. "guix/bzr-download.scm"
  239. "guix/cache.scm"
  240. "guix/channels.scm"
  241. "guix/ci.scm"
  242. "guix/colors.scm"
  243. "guix/combinators.scm"
  244. "guix/config.scm"
  245. "guix/cpio.scm"
  246. "guix/cpu.scm"
  247. "guix/cve.scm"
  248. "guix/cvs-download.scm"
  249. "guix/deprecation.scm"
  250. "guix/derivations.scm"
  251. "guix/describe.scm"
  252. "guix/diagnostics.scm"
  253. "guix/discovery.scm"
  254. "guix/docker.scm"
  255. "guix/download.scm"
  256. "guix/elf.scm"
  257. "guix/ftp-client.scm"
  258. "guix/gexp.scm"
  259. "guix/git-authenticate.scm"
  260. "guix/git-download.scm"
  261. "guix/git.scm"
  262. "guix/glob.scm"
  263. "guix/gnu-maintenance.scm"
  264. "guix/gnupg.scm"
  265. "guix/grafts.scm"
  266. "guix/graph.scm"
  267. "guix/hash.scm"
  268. "guix/hg-download.scm"
  269. "guix/http-client.scm"
  270. "guix/i18n.scm"
  271. "guix/inferior.scm"
  272. "guix/ipfs.scm"
  273. "guix/least-authority.scm"
  274. "guix/licenses.scm"
  275. "guix/lint.scm"
  276. "guix/man-db.scm"
  277. "guix/memoization.scm"
  278. "guix/modules.scm"
  279. "guix/monad-repl.scm"
  280. "guix/monads.scm"
  281. "guix/narinfo.scm"
  282. "guix/nar.scm"
  283. "guix/openpgp.scm"
  284. "guix/packages.scm"
  285. "guix/pki.scm"
  286. "guix/platform.scm"
  287. "guix/profiles.scm"
  288. "guix/profiling.scm"
  289. "guix/progress.scm"
  290. "guix/quirks.scm"
  291. "guix/read-print.scm"
  292. "guix/records.scm"
  293. "guix/remote.scm"
  294. "guix/repl.scm"
  295. "guix/search-paths.scm"
  296. "guix/self.scm"
  297. "guix/serialization.scm"
  298. "guix/sets.scm"
  299. "guix/ssh.scm"
  300. "guix/status.scm"
  301. "guix/store.scm"
  302. "guix/substitutes.scm"
  303. "guix/svn-download.scm"
  304. "guix/swh.scm"
  305. "guix/tests.scm"
  306. "guix/transformations.scm"
  307. "guix/ui.scm"
  308. "guix/upstream.scm"
  309. "guix/utils.scm"
  310. "guix/workers.scm"
  311. (make-regexp "^guix/platforms/")
  312. (make-regexp "^guix/scripts/")
  313. (make-regexp "^guix/store/"))))
  314. (define-team games
  315. (team 'games
  316. #:name "Games and Toys"
  317. #:description "Packaging programs for amusement."
  318. #:scope (list "gnu/packages/games.scm"
  319. "gnu/packages/game-development.scm"
  320. "gnu/packages/minetest.scm"
  321. "gnu/packages/esolangs.scm" ; granted, rather niche
  322. "gnu/packages/motti.scm"
  323. "guix/build/minetest-build-system.scm")))
  324. (define-team translations
  325. (team 'translations
  326. #:name "Translations"
  327. #:scope (list (make-regexp "^po/"))))
  328. (define-team installer
  329. (team 'installer
  330. #:name "Installer script and system installer"
  331. #:scope (list (make-regexp "^gnu/installer(\\.scm$|/)"))))
  332. (define-team home
  333. (team 'home
  334. #:name "Team for \"Guix Home\""
  335. #:scope (list (make-regexp "^(gnu|guix/scripts)/home(\\.scm$|/)")
  336. "tests/guix-home.sh"
  337. "tests/home-import.scm"
  338. "tests/home-services.scm")))
  339. (define-team mentors
  340. (team 'mentors
  341. #:name "Mentors"
  342. #:description
  343. "A group of mentors who chaperone contributions by newcomers."))
  344. (define-team mozilla
  345. (team 'mozilla
  346. #:name "Mozilla"
  347. #:description
  348. "Taking care about Icecat and Icedove, built from Mozilla Firefox
  349. and Thunderbird."
  350. #:scope (list "gnu/packages/gnuzilla.scm")))
  351. (define-team racket
  352. (team 'racket
  353. #:name "Racket team"
  354. #:description
  355. "The Racket language and Racket-based languages, Racket packages,
  356. Racket's variant of Chez Scheme, and development of a Racket build system and
  357. importer."
  358. #:scope (list "gnu/packages/racket.scm")))
  359. (define-member (person "Thiago Jung Bauermann"
  360. "bauermann@kolabnow.com")
  361. embedded-bootstrap translations)
  362. (define-member (person "Eric Bavier"
  363. "bavier@posteo.net")
  364. science)
  365. (define-member (person "Lars-Dominik Braun"
  366. "lars@6xq.net")
  367. python haskell)
  368. (define-member (person "Jonathan Brielmaier"
  369. "jonathan.brielmaier@web.de")
  370. mozilla)
  371. (define-member (person "Ludovic Courtès"
  372. "ludo@gnu.org")
  373. core home embedded-bootstrap mentors)
  374. (define-member (person "Andreas Enge"
  375. "andreas@enge.fr")
  376. science)
  377. (define-member (person "Björn Höfling"
  378. "bjoern.hoefling@bjoernhoefling.de")
  379. java)
  380. (define-member (person "Leo Famulari"
  381. "leo@famulari.name")
  382. kernel)
  383. (define-member (person "Efraim Flashner"
  384. "efraim@flashner.co.il")
  385. embedded-bootstrap julia rust science)
  386. (define-member (person "jgart"
  387. "jgart@dismail.de")
  388. python lisp mentors)
  389. (define-member (person "Guillaume Le Vaillant"
  390. "glv@posteo.net")
  391. lisp)
  392. (define-member (person "Julien Lepiller"
  393. "julien@lepiller.eu")
  394. java ocaml translations)
  395. (define-member (person "Philip McGrath"
  396. "philip@philipmcgrath.com")
  397. racket)
  398. (define-member (person "Mathieu Othacehe"
  399. "othacehe@gnu.org")
  400. core installer mentors)
  401. (define-member (person "Florian Pelz"
  402. "pelzflorian@pelzflorian.de")
  403. translations)
  404. (define-member (person "Liliana Marie Prikler"
  405. "liliana.prikler@gmail.com")
  406. emacs games)
  407. (define-member (person "Ricardo Wurmus"
  408. "rekado@elephly.net")
  409. r core mentors)
  410. (define-member (person "Christopher Baines"
  411. "mail@cbaines.net")
  412. core mentors ruby)
  413. (define-member (person "Andrew Tropin"
  414. "andrew@trop.in")
  415. home emacs)
  416. (define-member (person "pukkamustard"
  417. "pukkamustard@posteo.net")
  418. ocaml)
  419. (define-member (person "Josselin Poiret"
  420. "dev@jpoiret.xyz")
  421. core installer)
  422. (define-member (person "("
  423. "paren@disroot.org")
  424. home mentors)
  425. (define-member (person "Simon Tournier"
  426. "zimon.toutoune@gmail.com")
  427. julia core mentors)
  428. (define (find-team name)
  429. (or (hash-ref %teams (string->symbol name))
  430. (error (format #false
  431. "no such team: ~a~%" name))))
  432. (define (find-team-by-scope files)
  433. "Return the team(s) which scope matches at least one of the FILES, as list
  434. of file names as string."
  435. (hash-fold
  436. (lambda (key team acc)
  437. (if (any (lambda (file)
  438. (any (match-lambda
  439. ((? string? scope)
  440. (string=? scope file))
  441. ((? regexp? scope)
  442. (regexp-exec scope file)))
  443. (team-scope team)))
  444. files)
  445. (cons team acc)
  446. acc))
  447. '()
  448. %teams))
  449. (define (cc . teams)
  450. "Return arguments for `git send-email' to notify the members of the given
  451. TEAMS when a patch is received by Debbugs."
  452. (format #true
  453. "~{--add-header=\"X-Debbugs-Cc: ~a\"~^ ~}"
  454. (map person-email
  455. (delete-duplicates (append-map team-members teams) equal?))))
  456. (define* (list-members team #:optional port (prefix ""))
  457. "Print the members of the given TEAM."
  458. (define port* (or port (current-output-port)))
  459. (for-each
  460. (lambda (member)
  461. (format port*
  462. "~a~a <~a>~%"
  463. prefix
  464. (person-name member)
  465. (person-email member)))
  466. (team-members team)))
  467. (define (list-teams)
  468. "Print all teams, their scope and their members."
  469. (define port* (current-output-port))
  470. (define width* (%text-width))
  471. (hash-for-each
  472. (lambda (key team)
  473. (format port*
  474. "\
  475. id: ~a
  476. name: ~a
  477. description: ~a
  478. ~amembers:
  479. "
  480. (team-id team)
  481. (team-name team)
  482. (or (and=> (team-description team)
  483. (lambda (text)
  484. (string->recutils
  485. (fill-paragraph text width*
  486. (string-length "description: ")))))
  487. "<none>")
  488. (match (team-scope team)
  489. (() "")
  490. (scope (format #f "scope: ~{~s ~}~%" scope))))
  491. (list-members team port* "+ ")
  492. (newline))
  493. %teams))
  494. (define (diff-revisions rev-start rev-end)
  495. "Return the list of added, modified or removed files between REV-START
  496. and REV-END, two git revision strings."
  497. (let* ((repository (repository-open (getcwd)))
  498. (commit1 (commit-lookup repository
  499. (object-id
  500. (revparse-single repository rev-start))))
  501. (commit2 (commit-lookup repository
  502. (object-id
  503. (revparse-single repository rev-end))))
  504. (diff (diff-tree-to-tree repository
  505. (commit-tree commit1)
  506. (commit-tree commit2)))
  507. (files '()))
  508. (diff-foreach
  509. diff
  510. (lambda (delta progress)
  511. (set! files
  512. (cons (diff-file-path (diff-delta-old-file delta)) files))
  513. 0)
  514. (const 0)
  515. (const 0)
  516. (const 0))
  517. files))
  518. (define (main . args)
  519. (match args
  520. (("cc" . team-names)
  521. (apply cc (map find-team team-names)))
  522. (("cc-members" rev-start rev-end)
  523. (apply cc (find-team-by-scope
  524. (diff-revisions rev-start rev-end))))
  525. (("list-teams" . args)
  526. (list-teams))
  527. (("list-members" . team-names)
  528. (for-each
  529. (lambda (team-name)
  530. (list-members (find-team team-name)))
  531. team-names))
  532. (anything
  533. (format (current-error-port)
  534. "Usage: etc/teams.scm <command> [<args>]~%"))))
  535. (apply main (cdr (command-line)))