summaryrefslogtreecommitdiff
path: root/doc/contributing.zh_CN.texi
blob: ba8a824cade6245f1d0ad8f56dd5fd56f9873438 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
@node 贡献
@chapter 贡献

这个项目是大家合作的成果,我们需要你的帮助以更好地发展。请通过
@email{guix-devel@@gnu.org} 和 Freenode IRC 上的 @code{#guix} 联系我们。我们欢迎
您的想法、bug反馈、补丁,以及任何可能对项目有帮助的贡献。我们特别欢迎帮助我们打
包(@pxref{打包指导})。

@cindex 行为准则和贡献者
@cindex 贡献者契约
我们希望提供一个温暖、友好,并且没有骚扰的的环境,这样每个人都能尽最大努力贡献。
为了这个目的,我们的项目遵循“贡献者契约”,这个契约是根据
@url{http://contributor-covenant.org/}制定的。你可以在源代码目录里的
@file{CODE-OF-CONDUCT}文件里找到一份本地版。

贡献者在提交补丁和网上交流时不需要使用法律认可的名字。他们可以使用任何名字或者假
名。

@menu
* 从Git编译::             最新的并且最好的.
* 在安装之前运行Guix::  黑客技巧。
* 完美的配置::          正确的工具。
* 打包指导::             Growing the distribution.
* 代码风格::             开发者的卫生情况
* 提交补丁::             分享你的工作。
@end menu

@node 从Git编译
@section 从Git编译

如果你想折腾Guix本身,建议使用Git仓库里最新的版本:

@example
git clone https://git.savannah.gnu.org/git/guix.git
@end example

当从Git检出构建Guix时,除安装指导(@pxref{Requirements})里提及的软件包之外还需
要这些包。

@itemize
@item @url{http://gnu.org/software/autoconf/, GNU Autoconf};
@item @url{http://gnu.org/software/automake/, GNU Automake};
@item @url{http://gnu.org/software/gettext/, GNU Gettext};
@item @url{http://gnu.org/software/texinfo/, GNU Texinfo};
@item @url{http://www.graphviz.org/, Graphviz};
@item @url{http://www.gnu.org/software/help2man/, GNU Help2man (可选)}。
@end itemize

设置Guix开发环境的最简单的方式当然是使用Guix!下面这些命令启动一个shell,所有的
依赖和环境变量都为折腾Guix设置好了:

@example
guix environment guix
@end example

这个命令更多的信息请参考@xref{Invoking guix environment}。额外的依赖可以通过
@option{--ad-hoc}选项添加:

@example
guix environment guix --ad-hoc help2man git strace
@end example

运行 @command{./bootstrap} 以使用Autoconf和Automake生成编译系统的基础框架。如果
你的得到这样的错误:

@example
configure.ac:46: error: possibly undefined macro: PKG_CHECK_MODULES
@end example

@noindent
它可能意味着Autoconf无法找到由pkg-config提供的@file{pkg.m4}。请确保@file{pkg.m4}
可用。由Guile提供的@file{guile.m4}宏也类似。假如你的Automake安装在
@file{/usr/local},那么它不会从@file{/usr/share}里寻找@file{.m4}文件。这种情况下,
你必须执行下面这个命令:

@example
export ACLOCAL_PATH=/usr/share/aclocal
@end example

参考@xref{Macro Search Path,,, automake, The GNU Automake Manual}.

然后,像正常一样运行@command{./configure}。确保提供
@code{--localstatedir=@var{directory}}参数,@var{directory}是你当前系统的
@code{localstatedir}的值。(@pxref{The Store})

最后,用@code{make check}执行测试(@pxref{Running the Test Suite})。如果遇到任
何错误,请参考“安装指导”(@pxref{Installation})或者给
@email{guix-devel@@gnu.org, 邮件列表}发邮件。


@node 在安装之前运行Guix
@section 在安装之前运行Guix

为了保持一个合适的工作环境,你会发现在你的本地代码树里测试修改而不用安装它们会很
有用。TODO: So that you can distinguish between your ``end-user'' hat and your
``motley'' costume.

这样,即使你没有运行@code{make install},所有的命令行工具都可以使用。为此,你先
要有一个包含全部依赖的环境(@pxref{从Git编译}),然后,为所有的命令添加
前缀@command{./pre-inst-env}(@file{pre-inst-env}脚本在Guix编译树的最顶层,它由
@command{./configure}生成),如@footnote{@command{sudo}命令的@option{-E}参数
确保@code{GUILE_LOAD_PATH}被正确设置,从而@command{guix-daemon}和它使用的工具可
以找到它们需要的Guile模块。}:

@example
$ sudo -E ./pre-inst-env guix-daemon --build-users-group=guixbuild
$ ./pre-inst-env guix build hello
@end example

@noindent
类似的,对于使用Guix模块的Guile会话:

@example
$ ./pre-inst-env guile -c '(use-modules (guix utils)) (pk (%current-system))'

;;; ("x86_64-linux")
@end example

@noindent
@cindex REPL
@cindex read-eval-print loop
@dots{} and for a REPL (@pxref{Using Guile Interactively,,, guile, Guile
Reference Manual}):

@example
$ ./pre-inst-env guile
scheme@@(guile-user)> ,use(guix)
scheme@@(guile-user)> ,use(gnu)
scheme@@(guile-user)> (define snakes
                       (fold-packages
                         (lambda (package lst)
                           (if (string-prefix? "python"
                                               (package-name package))
                               (cons package lst)
                               lst))
                         '()))
scheme@@(guile-user)> (length snakes)
$1 = 361
@end example

@command{pre-inst-env}脚本设置为此好了所有必要的的环境变量,包括@env{PATH}和
@env{GUILE_LOAD_PATH}。

@command{./pre-inst-env guix pull} @emph{不} 会更新本地源代码树,它只更新符号链
接@file{~/.config/guix/current} (@pxref{Invoking guix pull})。如果你想更新本地源
代码树,请运行@command{git pull}。


@node 完美的配置
@section 完美的配置

折腾Guix的完美配置也是折腾Guile的完美配置@pxref{Using Guile in Emacs,,, guile,
Guile Reference Manual})。首先,你需要的不仅是一个编辑器,你需要
@url{http://www.gnu.org/software/emacs, Emacs},以及美妙的
@url{http://nongnu.org/geiser/, Geiser}。为此,请运行:

@example
guix package -i emacs guile emacs-geiser
@end example

Geiser允许在Emacs里进行交互式的、增长式的开发:buffer里的代码补全和执行,获取一
行的文档(docstrings),上下文敏感的补全,@kbd{M-.}跳转到对象定义,测试代码的
REPL,及更多(@pxref{Introduction,,, geiser, Geiser User Manual})。为了方便的
Guix开发,请确保修改Guile的加载路径(load path)以使其能从你的项目里找到源代码文
件。

@lisp
;; @r{假设Guix项目在 ~/src/guix.}
(with-eval-after-load 'geiser-guile
  (add-to-list 'geiser-guile-load-path "~/src/guix"))
@end lisp

真正编辑代码时别忘了Emacs自带了方便的Scheme模式。而且,一定不要错过
@url{http://www.emacswiki.org/emacs/ParEdit, Paredit}。它提供了直接操作语法树的
的功能,例如,用S-表达式替换父节点,为S-表达式添加、删除前后的括号,删除后面的S-
表达式,等等。

@cindex 代码片段
@cindex 模板
@cindex reducing boilerplate
在@file{etc/snippets}文件夹里,我们还为普通的git commit信息和软件包定义提供模板。
这些模板可以通过@url{http://joaotavora.github.io/yasnippet/, YASnippet}使用,它
可以把短的触发字符串扩展成交互式的文字片段。你可能希望将这个文件夹添加到Emacs的
@var{yas-snippet-dirs}变量里。

@lisp
;; @r{假设Guix项目在 ~/src/guix.}
(with-eval-after-load 'yasnippet
  (add-to-list 'yas-snippet-dirs "~/src/guix/etc/snippets"))
@end lisp

commit信息片段显示staged文件需要依赖@url{https://magit.vc/, Magit}。编辑commit信
息时,输入@code{add},然后按@kbd{TAB}就可以插入一段用于新增软件包的模板;输入
@code{update},然后按@kbd{TAB}可以插入一段更新软件包的模板;输入@code{https}然后
按@kbd{TAB}可以插入一段修改主页URI为HTTPS的模板。

@code{scheme-mode}最重要的模板可以通过输入@code{package...},然后按@kbd{TAB}触发。
这个片段还插入了触发字符串@code{origin...},以进一步展开。@code{origin}片段更进
一步的可能插入其它以@code{...}结尾的触发字符串,它们可以被继续展开。


@node 打包指导
@section 打包指导

@cindex 软件包, 创建
这个GNU发行版正在开发的早期阶段,可能缺少一些你喜欢的软件。这个章节介绍你可以怎
样帮助这个发行版成长。

自由软件通常以@dfn{源代码包}的形式分发,通常是包含完整代码的@file{tar.gz}包。添
加软件包到这个发行版意味着两件事:添加描述如何编译包的@dfn{配方}和一系列依赖软件,
以及添加配方之外的@dfn{软件包元数据},如一段文字描述和证书信息。

在Guix里所有这些信息都包含在@dfn{软件包定义}里。软件包定义提供了软件包的高层视角。
它们使用Scheme编程语言编写,事实上,对每个软件包我们都定义一个绑定到软件包定义的
的变量,并且从模块(@pxref{Package Modules})中导出那个变量。然而,深入的Scheme
知识@emph{不}是创建软件包的前提条件。若要了解软件包的更多信息,@pxref{Defining
Packages}。

一旦软件包定义准备好了,并且包存在Guix代码树的一个文件里,你可以用@command{guix
build} (@pxref{Invoking guix build})命令测试它。假设这个新软件包的名字叫做
@code{gnew},你可以在Guix编译树里运行这个命令(@pxref{在安装之前运行Guix}):

@example
./pre-inst-env guix build gnew --keep-failed
@end example

使用@code{--keep-failed}参数会保留失败的编译树,这可以使调试编译错误更容易。
@code{--log-file}也是一个调试时很有用的参数,它可以用来访问编译日志。

如果@command{guix}命令找不到这个软件包,那可能是因为源文件包含语法错误,或者缺少
导出软件包的@code{define-public}语句。为了查找错误,你可以用Guile导入这个模块以
了解这个错误的详情:

@example
./pre-inst-env guile -c '(use-modules (gnu packages gnew))'
@end example

一旦你的软件包可以正确编译,请给我们发送补丁(@pxref{提交补丁})。当然,
如果你需要帮助,我们也会很乐意帮助你。一旦补丁被提交到Guix仓库里,这个新的软件包
会被自动地在支持的平台上编译@url{http://hydra.gnu.org/jobset/gnu/master, our
continuous integration system}。

@cindex substituter
用户可以通过运行@command{guix pull}命令获取最新的软件包定义(@pxref{Invoking
guix pull})。当@code{@value{SUBSTITUTE-SERVER}}编译好这些软件包之后,安装这些软
件包时会自动从服务器(@pxref{Substitutes})上下载编译好的二进制包。唯一需要人工
干预的地方是评审和应用代码补丁。


@menu
* 软件自由::             什么可以进入这个发行版。
* 软件包命名::          名字里包含什么?
* 版本号::                当名字不够时
* 简介和描述::          帮助用户寻找合适的软件包
* Python模块::             接触英式的喜剧
* Perl模块::               小珍珠。
* Java包::                  喝咖啡休息。
* 字体::                   字体的乐趣。
@end menu

@node 软件自由
@subsection 软件自由

@c ===========================================================================
@c
@c This file was generated with po4a. Translate the source file.
@c
@c ===========================================================================
@c Adapted from http://www.gnu.org/philosophy/philosophy.html.
@cindex 自由软件
开发GNU操作系统是为了用户拥有计算的自由。GNU是@dfn{自由软件},这意味着它有
@url{http://www.gnu.org/philosophy/free-sw.html,四项重要的自由}:运行程序的自由,
以源代码形式学习和修改程序的自由,原样重新分发副本的自由,和分发修改后的版本的自
由。GNU发行版里包含的软件包只提供遵守这四项自由的软件。

此外,GNU发行版遵循
@url{http://www.gnu.org/distros/free-system-distribution-guidelines.html,自由软
件发行版准则}。这些准则拒绝非自由的固件和对非自由软件的推荐,并讨论解决商标和专
利的方法。

某些上游的软件包源代码包含一小部分违反上述准则的可选的子集,比如这个子集本身就是
非自由代码。这时,这些讨厌的代码需要用合适的补丁或者软件包定义(@pxref{Defining
Packages})里的@code{origin}里的代码片段移除。这样,@code{guix build --source}就
可以返回自由的源代码而不是未经修改的上游源代码。


@node 软件包命名
@subsection 软件包命名

@cindex 软件包名字
一个软件包事实上有两个名字:第一个是@emph{Scheme变量}的名字,即用
@code{define-public}定义的名字。通过这个名字,软件包可以被Scheme代码找到,如用作
其它软件包的输入。第二个名字是软件包定义里的@code{name}属性的字符串值。这个名字
用于软件包管理命令,如:@command{guix package},@command{guix build}

两个名字通常是相同的,常是上游项目名字转成小写字母并把下划线替换成连字符的结果。
比如,GNUnet转成@code{gnunet},SDL_net转成@code{sdl-net}。

我们不给库软件包添加@code{lib}前缀,除非它是项目官方名字的一部分。但是
@pxref{Python模块}和@ref{Perl模块}有关于Python和Perl语言的特殊规则。

字体软件包的名字处理起来不同,@pxref{字体}.


@node 版本号
@subsection 版本号

@cindex 软件包版本
我们通常只为每个自由软件的最新版本打包。但是有时候,比如对于版本不兼容的库,需要
有同一个软件包的两个或更多版本。它们需要使用不同的Scheme变量名。我们为最新的版本
使用@ref{软件包命名}里规定的名字,旧的版本使用加上后缀的名字,后缀是@code{-}
和可以区分开版本号的版本号的最小前缀。

软件包定义里的名字对于同一个软件包的所有版本都是相同的,并且不含有版本号。

例如,GTK+的2.24.20和3.9.12两个版本可以这样打包:

@example
(define-public gtk+
  (package
    (name "gtk+")
    (version "3.9.12")
    ...))
(define-public gtk+-2
  (package
    (name "gtk+")
    (version "2.24.20")
    ...))
@end example
如果我们还需要GTK+ 3.8.2,就这样打包
@example
(define-public gtk+-3.8
  (package
    (name "gtk+")
    (version "3.8.2")
    ...))
@end example

@c See <https://lists.gnu.org/archive/html/guix-devel/2016-01/msg00425.html>,
@c for a discussion of what follows.
@cindex 用于版本控制快照的版本号
有时候,我们为软件包上游的版本控制系统(VCS)的快照而不是正式发布版打包。这是特
殊情况,因为决定哪个是稳定版的权力应该属于上游开发者。然而,有时候这是必须的。那
么,我们该如何决定写在@code{version}里的版本号呢?

显然,我们需要让VCS快照的commit ID在版本号中体现出来,但是我们也需要确保版本号单
调递增,以便@command{guix package --upgrade}决定哪个版本号更新。由于commit ID,
尤其是Git的commit ID,不是单调递增的,我们添加一个每次升级快照时都手动增长的
revision数字。最后的版本号字符串看起来是这样:

@example
2.0.11-3.cabba9e
  ^    ^    ^
  |    |    `-- 上游的commit ID
  |    |
  |    `--- Guix软件包的revision
  |
最新的上游版本号
@end example

把@code{版本号}里的commit ID截短,比如只取7个数字,是一个好主意。它避免了美学上
的烦恼(假设美学在这里很重要),以及操作系统限制引起的问题(比如Linux内核的127字
节)。尽管如此,在@code{origin}里最好使用完整的commit ID,以避免混淆。

@example
(define my-package
  (let ((commit "c3f29bc928d5900971f65965feaae59e1272a3f7")
        (revision "1"))          ;Guix软件包的revision
    (package
      (version (git-version "0.9" revision commit))
      (source (origin
                (method git-fetch)
                (uri (git-reference
                      (url "git://example.org/my-package.git")
                      (commit commit)))
                (sha256 (base32 "1mbikn@dots{}"))
                (file-name (git-file-name name version))))
      ;; @dots{}
      )))
@end example

@node 简介和描述
@subsection 简介和描述

@cindex 软件包描述
@cindex 软件包简介
我们已经看到,GNU@tie{}Guix里的每个软件包都包含一个简介(synopsis)和一个描述
(description)(@pxref{Defining Packages})。简介和描述很重要:它们是
@command{guix package --search}搜索的信息,并且是帮助用户决定一个软件包是否符合
自己需求的重要信息。因此,打包的人应该关注怎样写它们的内容。

简介必须以大写字母开头,并且不能以句号结尾。它们不能以 ``a'' 或者 ``the'' 等没有
意义的词开头。例如 ``File-frobbing tool'' 要比 ``A tool that frobs files'' 更好。
简介需要说明软件包是什么--如 ``Core GNU utilities (file, text, shell)'',或者
它的用途--如 GNU@tie{}grep 的简介是 ``Print lines matching a pattern''。

Keep in mind that the synopsis must be meaningful for a very wide audience.
For example, ``Manipulate alignments in the SAM format'' might make sense
for a seasoned bioinformatics researcher, but might be fairly unhelpful or
even misleading to a non-specialized audience.  It is a good idea to come up
with a synopsis that gives an idea of the application domain of the
package.  In this example, this might give something like ``Manipulate
nucleotide sequence alignments'', which hopefully gives the user a better
idea of whether this is what they are looking for.

Descriptions should take between five and ten lines.  Use full sentences,
and avoid using acronyms without first introducing them.  Please avoid
marketing phrases such as ``world-leading'', ``industrial-strength'', and
``next-generation'', and avoid superlatives like ``the most
advanced''---they are not helpful to users looking for a package and may
even sound suspicious.  Instead, try to be factual, mentioning use cases and
features.

@cindex Texinfo markup, in package descriptions
Descriptions can include Texinfo markup, which is useful to introduce
ornaments such as @code{@@code} or @code{@@dfn}, bullet lists, or hyperlinks
(@pxref{Overview,,, texinfo, GNU Texinfo}).  However you should be careful
when using some characters for example @samp{@@} and curly braces which are
the basic special characters in Texinfo (@pxref{Special Characters,,,
texinfo, GNU Texinfo}).  User interfaces such as @command{guix package
--show} take care of rendering it appropriately.

Synopses and descriptions are translated by volunteers
@uref{http://translationproject.org/domain/guix-packages.html, at the
Translation Project} so that as many users as possible can read them in
their native language.  User interfaces search them and display them in the
language specified by the current locale.

To allow @command{xgettext} to extract them as translatable strings,
synopses and descriptions @emph{must be literal strings}.  This means that
you cannot use @code{string-append} or @code{format} to construct these
strings:

@lisp
(package
  ;; @dots{}
  (synopsis "This is translatable")
  (description (string-append "This is " "*not*" " translatable.")))
@end lisp

Translation is a lot of work so, as a packager, please pay even more
attention to your synopses and descriptions as every change may entail
additional work for translators.  In order to help them, it is possible to
make recommendations or instructions visible to them by inserting special
comments like this (@pxref{xgettext Invocation,,, gettext, GNU Gettext}):

@example
;; TRANSLATORS: "X11 resize-and-rotate" should not be translated.
(description "ARandR is designed to provide a simple visual front end
for the X11 resize-and-rotate (RandR) extension. @dots{}")
@end example


@node Python模块
@subsection Python模块

@cindex python
We currently package Python 2 and Python 3, under the Scheme variable names
@code{python-2} and @code{python} as explained in @ref{版本号}.  To
avoid confusion and naming clashes with other programming languages, it
seems desirable that the name of a package for a Python module contains the
word @code{python}.

Some modules are compatible with only one version of Python, others with
both.  If the package Foo compiles only with Python 3, we name it
@code{python-foo}; if it compiles only with Python 2, we name it
@code{python2-foo}. If it is compatible with both versions, we create two
packages with the corresponding names.

If a project already contains the word @code{python}, we drop this; for
instance, the module python-dateutil is packaged under the names
@code{python-dateutil} and @code{python2-dateutil}.  If the project name
starts with @code{py} (e.g.@: @code{pytz}), we keep it and prefix it as
described above.

@subsubsection Specifying Dependencies
@cindex inputs, for Python packages

Dependency information for Python packages is usually available in the
package source tree, with varying degrees of accuracy: in the
@file{setup.py} file, in @file{requirements.txt}, or in @file{tox.ini}.

Your mission, when writing a recipe for a Python package, is to map these
dependencies to the appropriate type of ``input'' (@pxref{package Reference,
inputs}).  Although the @code{pypi} importer normally does a good job
(@pxref{Invoking guix import}), you may want to check the following check
list to determine which dependency goes where.

@itemize

@item
We currently package Python 2 with @code{setuptools} and @code{pip}
installed like Python 3.4 has per default.  Thus you don't need to specify
either of these as an input.  @command{guix lint} will warn you if you do.

@item
Python dependencies required at run time go into @code{propagated-inputs}.
They are typically defined with the @code{install_requires} keyword in
@file{setup.py}, or in the @file{requirements.txt} file.

@item
Python packages required only at build time---e.g., those listed with the
@code{setup_requires} keyword in @file{setup.py}---or only for
testing---e.g., those in @code{tests_require}---go into
@code{native-inputs}.  The rationale is that (1) they do not need to be
propagated because they are not needed at run time, and (2) in a
cross-compilation context, it's the ``native'' input that we'd want.

Examples are the @code{pytest}, @code{mock}, and @code{nose} test
frameworks.  Of course if any of these packages is also required at
run-time, it needs to go to @code{propagated-inputs}.

@item
Anything that does not fall in the previous categories goes to
@code{inputs}, for example programs or C libraries required for building
Python packages containing C extensions.

@item
If a Python package has optional dependencies (@code{extras_require}), it is
up to you to decide whether to add them or not, based on their
usefulness/overhead ratio (@pxref{提交补丁, @command{guix size}}).

@end itemize


@node Perl模块
@subsection Perl模块

@cindex perl
Perl programs standing for themselves are named as any other package, using
the lowercase upstream name.  For Perl packages containing a single class,
we use the lowercase class name, replace all occurrences of @code{::} by
dashes and prepend the prefix @code{perl-}.  So the class @code{XML::Parser}
becomes @code{perl-xml-parser}.  Modules containing several classes keep
their lowercase upstream name and are also prepended by @code{perl-}.  Such
modules tend to have the word @code{perl} somewhere in their name, which
gets dropped in favor of the prefix.  For instance, @code{libwww-perl}
becomes @code{perl-libwww}.


@node Java包
@subsection Java包

@cindex java
Java programs standing for themselves are named as any other package, using
the lowercase upstream name.

To avoid confusion and naming clashes with other programming languages, it
is desirable that the name of a package for a Java package is prefixed with
@code{java-}.  If a project already contains the word @code{java}, we drop
this; for instance, the package @code{ngsjava} is packaged under the name
@code{java-ngs}.

For Java packages containing a single class or a small class hierarchy, we
use the lowercase class name, replace all occurrences of @code{.} by dashes
and prepend the prefix @code{java-}.  So the class @code{apache.commons.cli}
becomes package @code{java-apache-commons-cli}.


@node 字体
@subsection 字体

@cindex fonts
For fonts that are in general not installed by a user for typesetting
purposes, or that are distributed as part of a larger software package, we
rely on the general packaging rules for software; for instance, this applies
to the fonts delivered as part of the X.Org system or fonts that are part of
TeX Live.

To make it easier for a user to search for fonts, names for other packages
containing only fonts are constructed as follows, independently of the
upstream package name.

The name of a package containing only one font family starts with
@code{font-}; it is followed by the foundry name and a dash @code{-} if the
foundry is known, and the font family name, in which spaces are replaced by
dashes (and as usual, all upper case letters are transformed to lower
case).  For example, the Gentium font family by SIL is packaged under the
name @code{font-sil-gentium}.

For a package containing several font families, the name of the collection
is used in the place of the font family name.  For instance, the Liberation
fonts consist of three families, Liberation Sans, Liberation Serif and
Liberation Mono.  These could be packaged separately under the names
@code{font-liberation-sans} and so on; but as they are distributed together
under a common name, we prefer to package them together as
@code{font-liberation}.

In the case where several formats of the same font family or font collection
are packaged separately, a short form of the format, prepended by a dash, is
added to the package name.  We use @code{-ttf} for TrueType fonts,
@code{-otf} for OpenType fonts and @code{-type1} for PostScript Type 1
fonts.


@node 代码风格
@section 代码风格

In general our code follows the GNU Coding Standards (@pxref{Top,,,
standards, GNU Coding Standards}).  However, they do not say much about
Scheme, so here are some additional rules.

@menu
* Programming Paradigm::     How to compose your elements.
* Modules::                  Where to store your code?
* Data Types and Pattern Matching::  Implementing data structures.
* Formatting Code::          Writing conventions.
@end menu

@node Programming Paradigm
@subsection Programming Paradigm

Scheme code in Guix is written in a purely functional style.  One exception
is code that involves input/output, and procedures that implement low-level
concepts, such as the @code{memoize} procedure.

@node Modules
@subsection Modules

Guile modules that are meant to be used on the builder side must live in the
@code{(guix build @dots{})} name space.  They must not refer to other Guix
or GNU modules.  However, it is OK for a ``host-side'' module to use a
build-side module.

Modules that deal with the broader GNU system should be in the @code{(gnu
@dots{})} name space rather than @code{(guix @dots{})}.

@node Data Types and Pattern Matching
@subsection Data Types and Pattern Matching

The tendency in classical Lisp is to use lists to represent everything, and
then to browse them ``by hand'' using @code{car}, @code{cdr}, @code{cadr},
and co.  There are several problems with that style, notably the fact that
it is hard to read, error-prone, and a hindrance to proper type error
reports.

Guix code should define appropriate data types (for instance, using
@code{define-record-type*}) rather than abuse lists.  In addition, it should
use pattern matching, via Guile’s @code{(ice-9 match)} module, especially
when matching lists.

@node Formatting Code
@subsection Formatting Code

@cindex formatting code
@cindex coding style
When writing Scheme code, we follow common wisdom among Scheme programmers.
In general, we follow the @url{http://mumble.net/~campbell/scheme/style.txt,
Riastradh's Lisp Style Rules}.  This document happens to describe the
conventions mostly used in Guile’s code too.  It is very thoughtful and well
written, so please do read it.

Some special forms introduced in Guix, such as the @code{substitute*} macro,
have special indentation rules.  These are defined in the
@file{.dir-locals.el} file, which Emacs automatically uses.  Also note that
Emacs-Guix provides @code{guix-devel-mode} mode that indents and highlights
Guix code properly (@pxref{Development,,, emacs-guix, The Emacs-Guix
Reference Manual}).

@cindex indentation, of code
@cindex formatting, of code
If you do not use Emacs, please make sure to let your editor knows these
rules.  To automatically indent a package definition, you can also run:

@example
./etc/indent-code.el gnu/packages/@var{file}.scm @var{package}
@end example

@noindent
This automatically indents the definition of @var{package} in
@file{gnu/packages/@var{file}.scm} by running Emacs in batch mode.  To
indent a whole file, omit the second argument:

@example
./etc/indent-code.el gnu/services/@var{file}.scm
@end example

@cindex Vim, Scheme code editing
If you are editing code with Vim, we recommend that you run @code{:set
autoindent} so that your code is automatically indented as you type.
Additionally, @uref{https://www.vim.org/scripts/script.php?script_id=3998,
@code{paredit.vim}} may help you deal with all these parentheses.

We require all top-level procedures to carry a docstring.  This requirement
can be relaxed for simple private procedures in the @code{(guix build
@dots{})} name space, though.

Procedures should not have more than four positional parameters.  Use
keyword parameters for procedures that take more than four parameters.


@node 提交补丁
@section 提交补丁

Development is done using the Git distributed version control system.  Thus,
access to the repository is not strictly necessary.  We welcome
contributions in the form of patches as produced by @code{git format-patch}
sent to the @email{guix-patches@@gnu.org} mailing list.

This mailing list is backed by a Debbugs instance accessible at
@uref{https://bugs.gnu.org/guix-patches}, which allows us to keep track of
submissions.  Each message sent to that mailing list gets a new tracking
number assigned; people can then follow up on the submission by sending
email to @code{@var{NNN}@@debbugs.gnu.org}, where @var{NNN} is the tracking
number (@pxref{Sending a Patch Series}).

Please write commit logs in the ChangeLog format (@pxref{Change Logs,,,
standards, GNU Coding Standards}); you can check the commit history for
examples.

Before submitting a patch that adds or modifies a package definition, please
run through this check list:

@enumerate
@item
If the authors of the packaged software provide a cryptographic signature
for the release tarball, make an effort to verify the authenticity of the
archive.  For a detached GPG signature file this would be done with the
@code{gpg --verify} command.

@item
Take some time to provide an adequate synopsis and description for the
package.  @xref{简介和描述}, for some guidelines.

@item
Run @code{guix lint @var{package}}, where @var{package} is the name of the
new or modified package, and fix any errors it reports (@pxref{Invoking guix
lint}).

@item
Make sure the package builds on your platform, using @code{guix build
@var{package}}.

@item
We recommend you also try building the package on other supported
platforms.  As you may not have access to actual hardware platforms, we
recommend using the @code{qemu-binfmt-service-type} to emulate them.  In
order to enable it, add the following service to the list of services in
your @code{operating-system} configuration:

@example
(service qemu-binfmt-service-type
 (qemu-binfmt-configuration
   (platforms (lookup-qemu-platforms "arm" "aarch64" "mips64el"))
   (guix-support? #t)))
@end example

Then reconfigure your system.

You can then build packages for different platforms by specifying the
@code{--system} option.  For example, to build the "hello" package for the
armhf, aarch64, or mips64 architectures, you would run the following
commands, respectively:
@example
guix build --system=armhf-linux --rounds=2 hello
guix build --system=aarch64-linux --rounds=2 hello
guix build --system=mips64el-linux --rounds=2 hello
@end example

@item
@cindex bundling
Make sure the package does not use bundled copies of software already
available as separate packages.

Sometimes, packages include copies of the source code of their dependencies
as a convenience for users.  However, as a distribution, we want to make
sure that such packages end up using the copy we already have in the
distribution, if there is one.  This improves resource usage (the dependency
is built and stored only once), and allows the distribution to make
transverse changes such as applying security updates for a given software
package in a single place and have them affect the whole system---something
that bundled copies prevent.

@item
Take a look at the profile reported by @command{guix size} (@pxref{Invoking
guix size}).  This will allow you to notice references to other packages
unwillingly retained.  It may also help determine whether to split the
package (@pxref{Packages with Multiple Outputs}), and which optional
dependencies should be used.  In particular, avoid adding @code{texlive} as
a dependency: because of its extreme size, use @code{texlive-tiny} or
@code{texlive-union} instead.

@item
For important changes, check that dependent package (if applicable) are not
affected by the change; @code{guix refresh --list-dependent @var{package}}
will help you do that (@pxref{Invoking guix refresh}).

@c See <https://lists.gnu.org/archive/html/guix-devel/2016-10/msg00933.html>.
@cindex branching strategy
@cindex rebuild scheduling strategy
Depending on the number of dependent packages and thus the amount of
rebuilding induced, commits go to different branches, along these lines:

@table @asis
@item 300 dependent packages or less
@code{master} branch (non-disruptive changes).

@item between 300 and 1,200 dependent packages
@code{staging} branch (non-disruptive changes).  This branch is intended to
be merged in @code{master} every 3 weeks or so.  Topical changes (e.g., an
update of the GNOME stack) can instead go to a specific branch (say,
@code{gnome-updates}).

@item more than 1,200 dependent packages
@code{core-updates} branch (may include major and potentially disruptive
changes).  This branch is intended to be merged in @code{master} every 2.5
months or so.
@end table

All these branches are @uref{https://hydra.gnu.org/project/gnu, tracked by
our build farm} and merged into @code{master} once everything has been
successfully built.  This allows us to fix issues before they hit users, and
to reduce the window during which pre-built binaries are not available.

@c TODO: It would be good with badges on the website that tracks these
@c branches.  Or maybe even a status page.
Generally, branches other than @code{master} are considered @emph{frozen} if
there has been a recent evaluation, or there is a corresponding @code{-next}
branch.  Please ask on the mailing list or IRC if unsure where to place a
patch.

@item
@cindex determinism, of build processes
@cindex reproducible builds, checking
Check whether the package's build process is deterministic.  This typically
means checking whether an independent build of the package yields the exact
same result that you obtained, bit for bit.

A simple way to do that is by building the same package several times in a
row on your machine (@pxref{Invoking guix build}):

@example
guix build --rounds=2 my-package
@end example

This is enough to catch a class of common non-determinism issues, such as
timestamps or randomly-generated output in the build result.

Another option is to use @command{guix challenge} (@pxref{Invoking guix
challenge}).  You may run it once the package has been committed and built
by @code{@value{SUBSTITUTE-SERVER}} to check whether it obtains the same
result as you did.  Better yet: Find another machine that can build it and
run @command{guix publish}.  Since the remote build machine is likely
different from yours, this can catch non-determinism issues related to the
hardware---e.g., use of different instruction set extensions---or to the
operating system kernel---e.g., reliance on @code{uname} or @file{/proc}
files.

@item
When writing documentation, please use gender-neutral wording when referring
to people, such as @uref{https://en.wikipedia.org/wiki/Singular_they,
singular ``they''@comma{} ``their''@comma{} ``them''}, and so forth.

@item
Verify that your patch contains only one set of related changes.  Bundling
unrelated changes together makes reviewing harder and slower.

Examples of unrelated changes include the addition of several packages, or a
package update along with fixes to that package.

@item
Please follow our code formatting rules, possibly running the
@command{etc/indent-code.el} script to do that automatically for you
(@pxref{Formatting Code}).

@item
When possible, use mirrors in the source URL (@pxref{Invoking guix
download}).  Use reliable URLs, not generated ones.  For instance, GitHub
archives are not necessarily identical from one generation to the next, so
in this case it's often better to clone the repository.  Don't use the
@command{name} field in the URL: it is not very useful and if the name
changes, the URL will probably be wrong.

@end enumerate

When posting a patch to the mailing list, use @samp{[PATCH] @dots{}} as a
subject.  You may use your email client or the @command{git send-email}
command (@pxref{Sending a Patch Series}).  We prefer to get patches in plain
text messages, either inline or as MIME attachments.  You are advised to pay
attention if your email client changes anything like line breaks or
indentation which could potentially break the patches.

When a bug is resolved, please close the thread by sending an email to
@email{@var{NNN}-done@@debbugs.gnu.org}.

@unnumberedsubsec Sending a Patch Series
@anchor{Sending a Patch Series}
@cindex patch series
@cindex @code{git send-email}
@cindex @code{git-send-email}

@c Debbugs bug: https://debbugs.gnu.org/db/15/15361.html
When sending a patch series (e.g., using @code{git send-email}), please
first send one message to @email{guix-patches@@gnu.org}, and then send
subsequent patches to @email{@var{NNN}@@debbugs.gnu.org} to make sure they
are kept together.  See @uref{https://debbugs.gnu.org/Advanced.html, the
Debbugs documentation} for more information.