起步 自由软件的发布是一项双重任务。软件既要满足使用者,也要满足开发者。这两种需求不一定是冲突的,但是会为项目初期的展示增加复杂度。其中有些信息对两者都有用,有些只是对其中一类有用。对两种信息都应该依照展示的比例原则:描述的详细程度应该同读者在该阶段所应该花费的时间和努力程度相对应。更多的努力应该带来更多的回报。当这种关系发生偏差时,人们有可能很快失去信任并且停止投入精力。 这一点的必然结果就是形象的重要性。程序员们对这一点总是嗤之以鼻。对本质超越形式的热爱成了他们职业自豪感的一部分。所以毫不意外,许多程序员表现出对营销和公关工作的厌恶,同样,职业图形设计师往往也对程序员们的产品感到惊恐万状。 这是一个遗憾,因为有时候形式就是本质,并且项目的展示就是这种情形之一。例如,浏览网页的人对一个项目的第一观感就是来自网站的外观。这种观感的形成要早于任何一种实际的内容之前—包括文字和链接。不管这看起来多么不公平,人们无法不形成一个即时的第一印象。网站的形象向读者传递了一个信号,即网站的展示是否经过了精心安排。人类对检测心思的投入有着极为敏锐的感觉。我们中的大多数人都能在一瞥间看出一个网站是随便拉起来的还是经过认真思考的。这是你的项目展现出信息的第一步,它所建立起来的印象将对整个项目的后续部分施加影响。 因此,尽管本章的大部分篇幅谈论的是你应该用什么样的内容开始你的项目,但别忘了外观和感觉同样重要。因为项目的网站同时为使用者和开发者两类人服务的,相应的投入也要透明和有针对性。虽然这不是一本讨论网页设计的专著,但是当网站是为多种类型的读者服务时,有一条重要原则是值得一提的,在点击一个链接之前用户应该对它的去处有一个大概的了解。例如,当看到“用户文档”的链接时,明显应该是链接到用户文档,而不是开发者文档。运作一个项目一方面是为了提供信息,但同时也是提供舒适。当用户和开发者们正在犹豫要不要加入时,你应该在预期的地方用一套肯定性的标准来使他们安心。它表明项目有统一的管理,已经预估到了人们可能提出的问题,并且致力于在只花费提问者最少的精力的前提下来解答这些问题。通过显现这种充分准备的氛围,该项目发出了一个信息:“如果加入,你的时间不会被白白浪费,”而这正是人们想听到的。 用户和开发者的含义 用户开发者 这两个术语,指的是一个人在涉及的开源软件项目的身份,而非她在该项目之外的身份。 例如,如果一个开源项目是提供web开发的JavaScript的函数库,有人需要在自己的开发项目里使用这些函数库,那她就是一个“用户”(尽管她头衔可能是程序开发员)。但是如果她开始向upstream-- 也就是向该函数库项目 -- 修复bug,提供代码。那么这个时候她才算参与到了这个项目中来,并成为该项目一个“开发者”。 虽然在开源项目中很多开发者能变成用户,但也并不总是如此。特别是一些为了满足企业级要求的大型软件项目,该软件的开发者可能并不会是该软件直接的用户。 在一些主要服务程序员的项目中,用户和开发者的界限就很模糊了: 每一个用户都是潜在的开发者。但就算是针对非技术性型用户的项目,也有一定比例的用户会成为开发者。开源项目就应该让有兴趣的用户能很容易的转变为开发者。 如果你们在用“包装主机”网站 (参见 in ),这个选择的一个优点就是,这些网站有一个默认的、在各个项目里都通用的布局,而这就非常适合将项目呈现在世人面前。该布局可以在特定范围内自定义,但最初设计者眼前的默认设计就会提示您要尽可能包含访问者想要看见的信息。 但首先环顾四周 开始一个开源项目之前,给你一个重要的告诫: 一定要找找看是否有一个现存的项目已经做了你想做的。有很大的几率有人早于你已经解决了你想解决的问题。如果他们已经解决了它,并且在一个自由许可证下发布了他们的代码,那今天你就没有必要重新发明轮子了。当然有例外:如果是为了练习才开始一个项目,那现有的代码对你没用;或者你脑中的计划非常特别,你肯定不会有其他人有同样的想法,那你也不妨试试看。但总的来说没有理由不先看一看,而收获总是很大。如果常见的互联网搜索引擎发现不了什么,试试在https://github.com/, https://freshcode.club/, https://openhub.net/, 上找找看,同时自由软件基金会有一个自由软件的目录在https://directory.fsf.org/ 即使你找不到跟你的想法一模一样的项目,你也许能找到十分接近的,然后加入这个项目为它增加功能比你自己从零开始一个项目要更有意义。参考 in 里面有如何快速评估现有开源项目的介绍 从你所拥有的开始 你环顾了四周,没找到真正适合你的软件,因而决定开始一个新的项目。 现在应该做什么呢? 开始一个自由软件最难的部分是将个体的设想转化传达给公众。你或是你的团体也许对要做的事情已经十分明了,但是将这一目标清楚地传达给世界还需要付出一番努力。然而,那是必须花时间做的事情。你和其他的创建人必须决定你们项目的作用—也就是说,划定项目的范围,做什么,不做什么—然后撰写一份项目任务陈述。这部分通常不太难,但有时候能暴露出一些有关项目本质的臆想,甚至于分歧,那也没关系,现在解决这些问题总比拖到以后好。下一步就是将项目打包展示给公众, 而那纯粹是单调乏味的工作。 之所以这样说是因为打包的工作就是把大家都已经知道的东西组织和编辑成文件—这里所说的“大家”指的是到目前为止参与项目工作的人。因此,对于那些做这项工作的人来说,没有什么立竿见影的好处。他们并不需要一个README来了解整个项目的概况,也不需要一个设计文件或是用户手册。他们不需要仔细排列好的,与非正式而又普遍采用的软件源码发布方式相一致的代码树形图。对他们来说,无论代码怎么安排都没问题,因为他们已经对此十分熟悉,只要源码能够运行,他们就知道怎么用。甚至于,项目最根本的设计设想没有做成文件对他们来说也是无关紧要的;因为他们对那一方面也很熟悉了。 然而,新参与的人需要这些东西。好在他们并不是在一开始就需要全部的资料。在一个项目公之于众之前,你不必提供每一个有关的细节。在一个理想的世界里,每一个新的开源软件项目在开始的时候就具备了一个详细的设计文件,一套完整的用户手册(对已经计划好但还未实施的特性有特别的标识),漂亮地而又可移植地打好了包的代码,并且还可以在任何电脑系统平台上运行等等。然而在现实当中,做好上述各项工作是非常耗费时间的,可是一旦项目启动之后,这些工作可以指望一些自愿人员协助完成。 重要的必须做好展示这一步,以便新的参与者能够顺利通过开始时因对项目不熟悉而造成的障碍。设想自举过程中的第一步,就是将项目启动所需的能耗降到最低点。我听说过人们用切入能耗这个词来形容这一开端:即一个新的参与者在收获之前所必须付出的能量。一个项目的切入能耗控制得越低越好。你的首要任务就是将切入能耗降低到能够鼓励人参与项目工作的水平。 以下各小节分别描述了开始一个新项目的一个重要的方面。排列顺序大致是按照一个新的访问者将遇到的情形安排的,当然你在实际操作时可以不按照这个顺序进行。你可以将它们看作是一个检查列表。当你开始一个项目时,只要一一检查,确保每一步骤都做到了,或者在你省略某一部分时,至少你对将来可能出现的后果有把握就行了。 选择一个好名字 设想你是另外一个人,恰好听说过你的项目,或者是是在搜索一个软件来解决某个问题时碰巧看到了你的项目。他首先看到的是项目的名字。 一个好名字不会自然而然地使你的项目成功,而一个不好的名字也不会终结你的项目—当然了,一个真正糟糕的名字也许会,但是让我们首先假定谁也不会迫不及待地让自己的项目失败吧。确实,一个不好的名字会延缓他人接受该项目的速度,要么是因为人们不会认真对待它,要么是因为人们很难记住它的名字。 一个好名字: 告诉人们有关项目性质,或至少名字与性质是明显相关联的一些概念,这样人们看到名字时就知道了项目能做什么,那么人们以后便很容易想起这个名字。 便于记忆。在此,我们必须承认英语实际上已成为网络默认语言这一事实。“便于记忆”就意味着“便于能阅读英语的人记忆”。例如,某一非英语发音的双关语对于该语言之外的许多能阅读英语的人来说是很难理解的。要是这个双关语特别精彩并且令人难忘,那或许值得一试;但必须记住,这个名字在许多人的脑海里并不会产生在母语人士身上所有的效果。 不与另一个项目重名,也不侵犯任何商标权。这既表现职业美德,也是良好的法律意识。你要避免制造身份混乱。即便没有不同的东西重名的现象,我们现在要搞清楚网络上已有的东西已经很不容易了。 在前面里提及的资料有助于你发现是否另一个项目已经采用了你正在考虑的名字。美国的商标搜索见http://www.uspto.gov/ 尽可能成为.com.net、以及.org顶级域中的一个域名。你应该选择其中的一个,或许是.org吧,作为项目正式的网址;而另外两个网址都转发到前一个,这还可以防止其他人用项目的名字制造身份混乱。即使你打算将项目放在其它的网站空间上,(见),你仍然可以注册自己项目的域名,而转发至你存放项目的主页上。对用户来说,使用一个容易记忆的URL是十分有帮助的。顶级域名的重要性已经在下降了。现在,不少数量的项目的域名都用的例如:.io顶级域名,而不再使用 .com, .net, 或者 .org。我也不能预测未来大家选域名的心态,所以靠你自己判断吧,不过如果你能在所有重要的顶级域名中注册的话 ,那就这样做吧。 如果可以的话,要能作为用户名在https://twitter.com/ 和其他微型博客网站里,在这里参考更多和用户名与域名的关系 在重要的命名空间里注册名字 对于大型项目,能尽可能 多的在相关命名空间里面注册是一个不错的主意。这个命名空间我指的不仅仅是域名,而且还有一些用户会接触你们用到的账号名称(用户名)。如果你们在用户可能会搜索你们的地方都保持同一个名字的话,那么在他们决定更进一步参与之前,用户他们可以持续保持对你们的关注。 比如说,Gnome免费桌面项目的这个域名https://gnome.org/ 他们没有能够获得gnome.com或者gnome.net,但也无妨—如果你只有一个域名,而它就是.org,这也不错。.org通常都是人们第一个会想到去搜索开源项目名字的地方。如果他们不能注册"gnome.org"的话,一个常见的解决方法就是去使用"gnomeproject.org",很多项目都是这样做的。, 这个 https://twitter.com/gnome Twitter 界面,这个 https://identi.ca/gnome 在 Identi.ca的用户名https://identi.ca/ 是一个很多自由软件开发者使用的开源微博/社交网络, the https://github.com/gnome 在GitHub.com的用户名Gnome的主程序源代码在这里https://git.gnome.org/,因为太多开发者都熟悉GitHub,所以他们在GitHub也搞了一个镜像尽管他们有自己的IRC服务器(当然由他们自己控制这个频道的命名空间),在freenode IRC 网络(参见 )他们也有频道#gnome 所有这些让Gnome项目变得容易被发现:因为那正是潜在贡献者会去找的地方。当然了,Gnome是一个大型且复杂的项目,它有着成千上万的贡献者和小模块;因为到目前为止有非常多的方式去参与到Gnome中,所以对于Gnome来说,容易被发现的好处是比其他新项目的好处更大的。但是(就算是新的项目),在相关的命名空间里获取尽可能多的命名也绝不会对你的项目有负面影响。所以,当你开始一个项目,想想你想给项目取的名称,然后在你觉得可能用到的地方去注册吧。上面所提到的一些网站大概是一个不错的初始项目需要注册的名单,但你也可能需要去和你项目领域有关的网站去注册。 有一份清楚的使命陈述 人们找到了项目的网页之后,下一步就要看一份简短的项目描述,即使命陈述,以便(在30秒之内)决定他们是否对该项目有兴趣并获取更多信息。因此,这份使命陈述必须放在首页显著的位置,最好是紧贴着项目名字的下方。 使命陈述必须具体,紧凑;而最重要的是简短。以下是一个很好的例子,来自https://hadoop.apache.org/:
Apache™ Hadoop®项目为了可靠的可适应各种量级的分布式计算开发开源软件。 Apache Hadoop软件库是一个允许对存储在各个电脑中的大规模数据集通过简单的编程模型来分布式处理。它旨在从单个服务器扩展到数千台计算机,每台计算机都提供本地计算和存储。因为每个计算机都可能容易出现故障,所以软件库本身不是依靠硬件来提供高可用性,而是设计用于检测和处理应用程序层的故障,从而在计算机集群之上提供高可用性服务。
在仅仅四个句子里,依靠读者自己先前获取的知识,他们把需要说的都说得很清楚。这是一个重要的观点:设定一个基本的入门门槛也挺好。如果一个读者连"clusters" 和"high-availability"的意思都不了解,那这个读者可能也不需要使用到Hadoop,所以也没有必要为不懂这些的人再多解释。“旨在检测和处理应用程序层故障”,这一句将吸引到具有大规模计算集群经验的工程师—当他们看见这些词的时候,他们便知道Hadoop开发者是懂他们这行的,初次来的访问者也愿意进一步考虑Hadoop。 看过使命陈述之后仍对项目有兴趣的人自然想要了解更多的情况,或许要看一看用户文件和开发人员文件,最终可能下载一些东西。但在做这些事情以前,他们要确定这是一个开源项目。
声明项目是自由软件 网站的首页必须清清楚楚地写明这是一个开源项目。这看起来好像无需加以强调,但是你会惊讶有多少项目忽略了这一点。我见过不少自由软件网站,其首页不但没有说明该软件是在哪一个自由许可证下发布的,而且根本没在首页表明这是一个自由软件。有时候这一至关重要的信息被次要地放在了下载页,或是开发人员页,或是其它的一个需要多点击一次鼠标才能看到的一个地方。在一些极端的例子中,网页上哪儿都找不到自由许可证—只有下载软件打开之后才能看到。 别犯这个错误。这一忽略有可能让你失去许多潜在的开发人员和用户。务必在首页,也就是使命陈述的正下方,声明该项目是“自由软件”或是“开源软件”,并注明确切的许可证。有关选择许可证的快速指南,见本章后面的,而有关许可证问题的详细讨论见 至此,我们假想中的访问者已经决定—或许在随后的一分钟之内—他打算至少再花5分钟的时间研究一下这个项目。下面几个小节要描述他在之后的5分钟里将遇到的情形。 特性和需求列表 你应该列出一个简短的清单,说明软件支持的各种特性(如果某些特性还未完成,也可以列出,但是在旁边注明计划中”或“建设中”),以及运行该软件所要求的系统环境。列这份清单时,你只要设想一个人请你简短地介绍这个软件的特性/需求是什么。通常,那只是按照逻辑对使命陈述作进一步的扩充。例如,使命陈述可能写的是:
创建一个全文索引器并配备丰富API的搜索引擎,用于编程人员搜索大批量文本文件。
特性和需求清单将列出更详细的内容,对使命陈述的范围加以说明:
特性: 搜索纯文本,HTML和XML文件 字或词搜索 (计划中)模糊匹配 (计划中)增量更新索引 (计划中)索引远程站点 需求: Python 3.2或更高版本 足够的硬盘空间以储存索引(大约原文件大小的2倍)
有了这样的信息,读者便能很快地决定这个软件是否适用于他们,也可以考虑是否以开发人员的身份参与其中。
开发状态 人们总是希望了解一个项目的状况。对新的项目,他们想知道项目的承诺和现实之间存在着多大的距离。对成熟的项目,他们想知道维护得如何,新发布的频率怎样,以及对Bug报告反应的及时性等等。 要回答这些问题有很多方法。其中一种方法是:建立开发状态页,列出项目的近期目标和需求(例如,需要具备某方面专长的开发人员)。开发状态页也可以列出过去发布的记录,其中包含特性清单,以便访问者了解项目是如何定义“进展”的,并根据这一定义了解项目进展的速度。一些项目把他们的开发状态页面做成一个路线图:过去的进度就显示发生的时间,未来的进度安排就写上预期实现的日期。 另一个方式—与第一个方法并不互斥,事实上与之结合会更有效果—是在项目的首页和/或其开发人员登陆页面中嵌入各种自动维护的计数器和指示器,显示各种信息,总体上可以展示项目的开发状态和进度。 例如说,一个公告或新闻面板来显示新闻项目、一个Twitter或者别的微博来显示与项目指定的主题标签匹配的通知、一个显示最近发布项目的时间表、一个展示最近bug修复情况(提出的bug和解决的bug)的面板、再一个显示邮件列表和讨论活动等等。每一个面板都是一个进一步了解其详细情况的入口,比如说:点击“最近的bugs”面板,页面会跳转到全部bug的记录日志中,至少也要给一个下拉菜单显示更多的bug追踪信息。 实际上,这里杂糅了两种略有不同的“开发状态”的含义。一种是正式的:这个项目距离既定的目标还有多远,现在开发的速度怎么样。另一种不那么正式,但也同样有用:这个项目有多活跃?是不是在正常运作?这里的人是不是完成了任务。通常后面这个概念是来访者最为关心的,而一个项目是否完成了它的预期并不显得那么重要,因为(在访客心中)更重要的是这个项目有没有一个活跃的开发者社区。 这两种开放状态的概念,当然是互相关联的,而且一个善于展示的项目会把两者都展现出来。通常信息会分放在两个部分,一个是项目的首页(充分展示两种开发状态的概览),另一个是面向开发者的页面。 案例:Lauchpad状态指示器 一个在展示面向开发者状态显示器很不错的网站就是 Launchpad.net。它有点不同寻常,因为有些项目将其作为首要的展示信息的平台,另一些项目只在上面发布安装包(或者更确切地说,Launchpad是专门用于支持Ubuntu GNU / Linux操作系统打包特定程序的“项目”的主要站点) 。无论是上面两种中的哪种,一个项目在Launchpad上的页面都会显示其各种自动更新的状态指示器,可以由此快速了解项目的开发状况。尽管简单地模仿Launchpad页面不是一个好主意—你自己的项目也应该仔细思考采取什么指示器—但Launchpad页面提供的都是很好的例子,说不定就能用在你的项目里。从这个项目的顶上往下滑动滚轮,https://launchpad.net/drizzle or https://launchpad.net/inkscape然后随意挑选两个看看吧。 开发状态应该始终反映真实情况 别因为你的项目看起来没准备好而感到害怕,也不要向夸大开发状态的诱惑妥协。谁都清楚软件是分阶段开发的产品;你不必觉得难以开口说出:“这是仍带有Bug的alpha软件,它可以运行。而且至少有时候能正常工作,但你使用这个软件就得自己承担风险。”这类语言不会吓跑你在这个阶段需要的开发人员。然而,对于用户来说,最糟糕的事情莫过于在软件准备好之前就吸引用户。一旦冠上了稳定性差或是Bug多多的名声,软件就很难再正名了。采取保守的策略对长远的目标是非常有益的;软件的稳定性超出用户的预期总比达不到用户的期望好得多,而给用户惊喜就会给产品带来最佳口碑。 Alpha和Beta 术语alpha这个词通常指的是第一次发布,但是用户可以使用该软件进行工作,并且软件也具备了最初计划的所有功能,但已知的Bug仍然存在。Alpha软件的主要目的在于获取回馈,以便开发人员了解他们应该做什么。Alpha软件通常可以自由的更换API和功能。 下一个阶段,beta是指软件的API已经基本完善,所有影响大的Bug都已经被消灭了,但是软件还未经过足够的测试,因而还不能正式发布。Beta软件的目的有二,一是在未发现Bug的情况下正式发布软件,二是提供给开发人员详细的回馈,以便他们能够尽快解决问题之后正式发布软件。在Beta软件系列中,API和功能不到万不得已就不该改变了。 下载 应该可以以标准格式下载软件的源代码。在一个项目刚起步时,二进制(可执行的)软件包不是必要的,除非该软件的构建和依赖要求相当复杂,以至于仅仅运行该软件就需要大量的人力投入。 (如果情况是那样的话,该项目也将很难吸引开发人员的参与!) 发行机制应该尽量做到方便,标准化以及清楚无误。假如你要根除一种疾病,你分发的药物不会是需要一种非标准化的注射器来操作的吧。同样的道理,软件应该与标准化的构造和安装方法相一致;一个软件距离标准化越远,用户和开发人员放弃该软件并且一头雾水地离开的可能性就越大。 那听起来是显而易见的道理,但是许多项目往往等到很晚的时候才动手解决标准化安装程序,因为他们总是告诉自己这一步什么时候都可以做:“等到代码接近完工的时候再来解决这些所有的问题吧。”殊不知在拖延完成软件建设和安装程序这类枯燥工作的时候,他们实际上是在推迟完成代码的时间—因为他们让一些本来可以为软件编程做贡献的开发人员失去了兴趣。最糟糕的是,他们根本就不知道他们失去了那些开发人员,因为那是一连串无果而终的一个过程:某人访问了一个网页,下载了软件,试图参与构建,失败了,放弃而离开了。除了访问者本人以外,谁会知道发生了这一切?项目参与者中谁也不会意识到这位访问者的兴趣,然而 一个良好的意愿在悄无声息中便被扼杀了。 枯燥但具有高回报的工作应该尽早完成,而通过良好包装便能够大大降低进入项目障碍的工作显然是具有很高的回报率的。 当你发布一个可以下载的软件包时,至关重要的一点是给予这一次发布一个独一无二的版本号码,以便人们对两次发布加以比较,从而了解哪些东西被替代了。有关版本编号的详细讨论见,而构建和安装程序标准化的详细内容见以及 版本控制和Bug跟踪访问 下载安装包对于只想安装使用该软件的人来说还可以,但对于想要调试或添加新功能的人来说就不够了。每晚对源代码的快照能够起到帮助的作用,但若是对于一个蓬勃发展的开源社区来说的话,就显得不够精细了。人们需要一个对最新源代码能够实时访问的途径,并能够针对该版本的源代码提交修改意见。 很好的一个解决方案就是使用版本控制系统—特别地,一个在线公开访问的版本控制仓库(version controlled repository),任何人都可以查看项目的文件和更新。一个版本控制仓库—对开发者和用户来说—都是一个项目在努力让大家参与其中的信号。目前为止,很多的开源项目都在用https://github.com/,它为开源项目提供无限制的自由公开版本控制储存服务。尽管Github并不是唯一选择,也不是唯一好的选择,但对于绝大部分项目来说,它是很合理的虽然GitHub是基于Git这个开源版本控制系统,但运营Github网页服务的代码本身却并非是开源的。这是否会对你的项目造成困扰?我将在这里进一步讨论 in 。版本控制架构的细节讨论在这里属于. 对于项目的Bug跟踪系统来说,也是同样的道理。Bug跟踪系统之所以重要不只因为它对开发人员十分有用,而且对关注项目的人来说是一种标志。在许多人看来,一个可以进入的Bug数据库是一个项目是否严肃认真的重要标志之一。—再者,数据库中的Bug数量越多,项目看起来越好。这听起来似乎有悖常理,但是请记住Bug数量的记录实际上取决于三个因素:软件中存在的Bug绝对数量,使用该软件的用户人数,以及用户记录新发现的Bug的方便程度。在这三个因素当中,后两个比前一个重要得多。任何具有一定规模和复杂性的软件基本上都存在一定数量有待被发现的Bug。真正的问题是,一个项目在记录和优先解决Bug问题方面做得有多好?如果一个项目有一个较大而又维护得很好的Bug数据库(意思是bug问题得到及时地回应,重复bug被合并等等),那么这个项目就会比那些没有Bug数据库,或者Bug数据库里空空如也的项目给予人们更好的印象。 当然,如果你的项目刚刚起步,那么Bug数据库里就只有为数不多的Bug,而对此你也没有什么办法。但是如果在开发状况页强调项目仍处于初创期,且人们看到bug数据库里大多数的文档都是近期建立的,他们便可以由此推断出该项目仍然有良好的解决,也就不会因为看到相对较低的已经记录的Bug绝对数量而产生不适当的警觉。For a more thorough argument that bug reports should be treated as good news, see 如果想看关于bug跟踪系统更详细的介绍,参见这里http://www.rants.org/2010/01/10/bugs-users-and-tech-debt/,里面介绍了bug数据库的累积并不是代表了技术债务(Technical debt)https://en.wikipedia.org/wiki/Technical_debt) 而是反映了用户的积极参与。 请注意Bug跟踪系统的用途不止追踪软件的Bug,而且也用来跟踪扩展请求,文档变更,待解决的任务,以及其它一些问题。运行一个Bug跟踪系统的详细内容见中的,所以在此我就不赘述了。重要的是,Bug跟踪一定要显示出来,而且要确保项目的首页上便能看到这一点。 沟通渠道 项目的访客通常都希望知道如何能联系上参与项目的有关人员。提供邮件列表地址、聊天室、IRC频道()、以及任何其它形式的论坛,以便其他参与项目的人同样可以联系上。告诉人们你和项目的其他有关人员都在邮件列表上,因而人们便知道他们有途径将回馈传递给开发人员。你在邮件列表上并不意味着你承诺回答所有的问题,也不等于你要满足所有人提出的有关特性的要求。长远来看,大多数用户或许根本从不参与论坛,然而,如果他们知道他们需要的时候可以那样做,那对他们就是一种欣慰。 在项目开发初期,没有必要将用户论坛与开发人员论坛分开。更好的办法是让所有与软件有关的人员在“同一间屋子”里进行交谈。在早期使用软件的人当中,开发人员与用户之间的界线通常很模糊;不是没有界线,但是开发人员与用户之间的比例在项目早期远远高于后面的阶段。尽管我们不能假设每一位早期与项目有关的人都是想要介入软件开发的编程人员,但是我们可以肯定他们至少很有兴趣地关注项目发展中进行的讨论,并了解项目发展的方向。 由于本章只讨论项目的初建,所以在此我们只要说明有必要建立以上所说的交流论坛就行了。稍后,在中的,我们将讨论在什么地方以及如何建立这样的论坛,及可能需要的协调和其它方面的管理,另外,在时机成熟的时候,如何分离用户与开发人员的论坛而避免造成无法逾越的鸿沟。 开发者指南 如果有人考虑参与项目,她会寻找开发者指南。与社会性文档相比,开发者指南通常没有很多的技巧:只需要解释开发者之间,以及与用户之间如何交互,以及如何最终完成任务。 这部分的细节可以看中的,但开发指南的基本元素包括:与其它开发者交流论坛的链接 报告Bug和提交补丁的指导 说明进行开发的方法—项目是仁慈专制、还是民主的、还是其它。 对于“专制”这里没有任何轻蔑的含义。如果存在一个开发者对所有变更拥有否决权,这完全没有问题。许多成功的项目以这种方式进行。关键是项目能够说出来它的做法。一个假装民主的独裁会让人厌恶;如果独裁者只要有能力并被信任,一切都会很好。(参见 位于 你就会明白为什么在开源项目里的独裁和生活中其他的独裁不一样。) http://subversion.apache.org/docs/community-guide/这是一个挺不错的开发者手册,另外Libreoffice的手册也是一个不错的例子: https://wiki.documentfoundation.org/Development 如果项目有写一个行为准则(see ),那么开发者手册也应有个链接指向它。 为程序员提供单独的软件指导的问题会在本章后面的讨论。 文档 文档非常必要。需要有一些用户可以读的内容,即使它非常基本和不完整。在初期这样做确实是一件“苦差事”,经常成为新开源项目的第一个失败之处。提出使命声明和特性列表、选择一个许可证、概述开发状态—这都是相对的小任务,完成后通常可以不必返回继续工作。而另一方面,文档永远没有真正的结束,这可能也是人们总是延迟开始文档的一个原因。 一个隐伏的事实是,文档对于编写者的功用与阅读者的功用是相反的。对于初始用户来说最重要的是基础文档:如何快速配置软件,软件如何工作的概述以及一些常规操作的指导。而这些通常是编写者所非常熟悉的内容—以至于很难从读者的角度看问题,因而他们不会费力去表述一些非常明显而不值一提的步骤。 对这个问题没有神奇的解决办法。必须有人坐下来写好内容,然后交给普通的用户来验证它的质量。使用简单和容易编辑的格式,例如HTML、纯文本、Texinfo或一些XML的变种—便于在激励下可以轻型和快速的作出改进一开始你并不用太担心选择一个正确的格式,如果未来想换的话,随时可以用这个自动转换:http://johnmacfarlane.net/pandoc/.。这不仅是为了消除最初作者进行增量改进所带来的代价,也是为了希望修改文档的新加入者。 一个保证基本初始文档完成的方法是预先限制其范围。这种方法至少不会让我们感觉是在完成一个开放结尾的任务。一个经验是它必须达到下面的最低标准: 告诉读者他们所需的技术技能。 清楚和完整的描述如何配置软件,并在文档的开头部分告诉用户如何运行确认安装成功的诊断测试或简单命令。启动文档有时候比使用文档更重要。一个人投入到软件安装和开始的努力越多,她就越有可能持续的搞明白没有很好文档描述的高级功能。当人们放弃时,他们会很早就放弃;因此,在早期阶段,例如安装时,需要最多的支持。 提供一个普通任务的教程式的实例。很显然,不同任务的例子越多越好,但是时间有限,最好还是选择一个任务并完整的完成它。一旦人们看到这个软件可以使用,他们会开始探索其他需要的功能—如果你足够幸运,他们会自己补充文档。这将会让我们到下一点... 标示文档中未完成的部分。通过向读者展示这些不足,可以实现你与他们观点的联盟。你的移情作用可以使他们恢复信心,不必为确定什么是项目最重要的事情而挣扎。这些标示不需要承诺填补这些空白的期限—它等于是合情合理的公开征集志愿者。 最后一点在很多的地方都很重要,实际上,并可以应用到整个项目中,而不仅仅是文档中。开源领域中一个都知道的问题就是项目规范。你不必夸大项目的这种短处,你只需小心冷静的识别出需要这种规范(说明文档、Bug跟踪数据库或邮件列表讨论中都可以)的场景。就项目而言,没有人会视其为失败主义,也不会认为这是对在特定日期完成的承诺,除非项目明确作出这种承诺。因为使用软件的所有人都会发现这种不足,他们最好能在心理上做好准备—然后项目就有了解决这些问题的坚实知识。 维护FAQ 一个FAQ(“常见问题列表”)就教育意义的回报来讲,可能是最好的投资之一。非常提倡将FAQ调整为用户和开发者实际提出的问题—而不应该是你期望他们提出的问题—因此,一个维护良好的FAQ可以让咨询者从中准确的找到寻找的答案。在遇到问题时,FAQ通常是用户首先查找的地方,甚至比正式手册更受人偏爱,可能成为其他站点链接最多的文档。 但很不幸,你不可能在项目的开始就完成FAQ。好的FAQ不是写成的,而是长成的。它们是通过定义响应文档,随着人们对软件的日常使用而进化。因为不能预感到用户将会提出的问题,所以我们无法从头开始编写有用的FAQ。 因此,不要在这方面浪费时间了。但无论如何,你或许会发现创建一个FAQ的空白模板会很有用,很明显这样可以帮助人们在项目进行中贡献问题和答案。此时,最重要的性质不是完整,而是方便:如果添加FAQ非常简单,人们就会去添加。 (正确的FAQ维护应该是不琐碎和具迷惑性的问题,将会在下面部分地方讨论 位于 , 位于 , 和 位于 .) 文档的可用性 在两个地方必须有文档:在线(直接在网站上),以及软件可下载分发版本(见)中。它必须以可浏览的形式在线,因为通常人们会在第一次下载软件之前首先阅读文档,以决定是否下载。但是也必须和软件配套,因为原则上下载中必须包括使用软件包的所有必须内容。 对于在线文档,要确定有一个指向包含完整文档的(请在链接旁注明"monolithic"或"all-in-one"或"single large page",以提醒人们知道需要更长的下载时间)单独HTML页的链接。这是因为人们经常会在整个文档中寻找特定的词汇或短语。通常是他们已经知道他们在找什么;只是记不住具体的章节。对于此类人,最郁闷的就是遇到一个目录页面、然后是指导页面、然后是安装指导等等。当页面是如此琐碎时,浏览器的搜索功能将变得毫无作用。分页的样式适合那些知道他们所需章节,或是从头到尾阅读的人。但这不是访问文档的常规方式。通常是某人已经熟悉了软件,返回来搜索特定的词汇或短语。如果未能提供一个单独的、可搜索的文档会让他们活的很辛苦。 开发者文档 开发者文档主要为了帮助程序员理解代码,从而修改和扩展软件。这与更关注社交性而不是技术性的开发者指南有些许不同。开发者指南告诉程序员如何与代码本身打交道。为了方便,这两个文档通常会整理为一份文档(例如前面提到的http://subversion.apache.org/docs/community-guide/),但是这不是必须的。 尽管开发者文档可能很有用,但也没有为了它而影响发布。只要原始作者还在而且愿意,就可以回答关于代码的问题,一开始这就足够了。实际上,反复回答相同的问题是编写这个文档的动力所在。但即使文档还没有写,坚定地参与者也依然会设法以自己的方式处理代码。驱使人们花时间研究代码基的原因是他们发现这些代码对他们有用。如果人们相信这一点,他们就会花时间去搞明白;如果他们不相信,再多的开发者文档也留不住他们。 如果你有时间为一个读者写文档,那还是写给所有用户吧。所有用户的文档,和开发者文档有同样的效果;为软件工作的程序员一定对如何使用也非常熟悉。之后,当你看到程序员反复询问相同的问题时,你就应该为他们编写单独的文档。 一些项目使用wiki作为初始文档,甚至作为他们主要的文档。在我的经验里,只有文档是被少数认可文档的组织方式和包含内容的成员编辑时,才能正常工作。更多细节在 如果文档工作流程的基础结构看起来令人生畏,那么你可以考虑使用 https://readthedocs.org/。现在很多项目都依靠这个来自动完成文档的构建。这个网站能帮你转换格式,并且集成了版本控制仓库功能(所以文档的重建是可以自动完成的),同时它还能做很多其他单调的任务,这样一来你和其他参与者都能更专注于内容开发了。 输出和屏幕截图实例 如果一个项目包含图形化的用户界面,或者生成图形和其他特别的输出,那么就应该将这些样例放到项目网站上。如果是界面,那应该是截图又或者一个简短的(四分钟以内)有字幕和旁白的短视频。至于输出什么比较好呢?一般来说截图或者能够下载的样本文件就行。至于基于网页的程序,那么一个demo就是最好的了,当然前提是这个程序能够做出demo来。 最重要的是即时满足人们渴望看见的东西,当然是以他们期待的方式。单个屏幕截图或视频比描述性文本和邮件列表聊天的段落更具说服力,因为它证明了该软件能够运行。尽管代码可能还有bug,或者难以安装,亦或者不兼容 很多设备,但是基于图像的证据就在告诉人们,只要各方面都做到位的话,这个软件是可以正常运行的。 保证视频都很简洁, <emphasis>告诉大家</emphasis>它们很简洁。 如果你有一个关于你项目的视频介绍,保持他比四分钟更短,并且保证用户在点击视频之前就知道视频的长度了。这符合前面提到的“缩放演示原则”:通过消除所有风险,来告诉用户观看视频是一个容易的不错的了解项目的方式。访问者更有可能点击“观看我们的3分钟视频”的链接,而不是点击“观看我们的视频”的链接,因为在前一种情况下,他们知道他们在点击之前会遇到什么—这样的话她们看的会更认真,也一般不会看一半就不看了,因为看之前在心里就准备好了预期的时间。 至于四分钟限制来自何处:这是一个科学事实,通过同一个实验对象(匿名)的多次尝试确定的。当然,该限制不适用于教程或其他教学材料; 它仅适用于介绍性视频。 如果你还没有用于录制桌面交互视频的首选软件:而你又在使用GNOME 3桌面管理器,则可以使用其内置屏幕录制功能(参见 https://help.gnome.org/users/gnome-help/stable/screen-shot-record.html.en#screencast—只要按下 Ctl+Alt+Shift+R 就能开始录像,然后再一次按下 Ctl+Alt+Shift+R 就能停止)。当然还有很多开源的视频编辑器; OpenShot 用来编辑录制以后的视频还是挺不错的。 还有一些东西需要放置到网站中,如果你有时间,或者如果出于某种原因而显得特别合适:一个新闻页、一个项目历史页、一个相关链接页、站点搜索特性和捐赠页等等。开始时这些都不是必要的,但将来要一直留意。 上线 我们应该把项目的材料都放在什么地方呢? 当然是放在一个网站上面—但是这个答案的完整版就不是那么简单了。 很多项目对于主要呈现给用户看的页面—就是那种有各种漂亮图片和“About”页面写了清晰的介绍并附上视频诸如此类的东西—和给开发者看的页面有着天壤之别。在开发者页面里一切都显得有点不如人意,例如在等宽字体和不可穿透的缩写中充满了间距紧密的文本. 好吧,我夸张了一点。无论如何,在项目的早期阶段,区分这两个受众并不是那么重要。大多数感兴趣的访问者将是开发人员,或者至少是那些愿意尝试新代码的人。随着时间的推移,您可能会发现有必要去拥有一个面向用户的站点(当然,如果你的项目是代码库,那些“用户”可能是其他程序员),并且对于那些有兴趣参与开发的人来说,还需要一个相对独立的协作区域。后者将具有代码存储库,错误跟踪器,开发百科,开发邮件列表的链接等。这两个站点应该相互链接,特别是面向用户的站点应该清楚地表明项目是开源的和哪里可以找到开源开发活动。 过去,许多项目都是自己设置开发人员站点和网站的基础架构。但最近十多年来,大部分开源项目—几乎所有的新项目—就直接用"canned hosting"网站提供的服务。到目前2018年为止最流行的还是GitHub (https://github.com/),如果你没有别的偏好的话,你可能也就用GitHub了吧,很多开发者都已经熟悉了这个网站并有自己的账号了。关于选取这类站点的更多细节以及介绍,请参见 in
选择许可证并应用 这部分是关于选择许可证的快速粗糙指南。阅读可以理解不同许可证的法律含义细节,以及这些许可证如何影响人们将你的软件与其他自由软件混合的能力。 同义词: "free software license", "FSF-approved", "open source license" 和 "OSI-approved" 术语"free software license"和"open source license"本质上就是同意的,在本书中我也一直把二者视为等价。 严格意义上来说,前面那个术语更多指的是Free Software Foundation组织确认过的许可协议,包括为开源软件提供必要的“四种自由”。(参见 https://www.gnu.org/philosophy/free-sw.html), 而后面那个术语指的是由Open Source Initiative确认的符合开源定义的协议(https://opensource.org/osd). 然而,如果你阅读FSF和OSI关于自由软件的定义,你会发现对自由的定义是一致的。—这也斌不奇怪,正如 位于 解释的那样。那么接下来不可避免的结果就是两个也差不多的许可协议。尽管实际上他们各自准许的协议有轻微的差别,但是对我们做项目的并没有太多影响—以及其他很多实用的地方也都差别不大。通常如果不是很常用的许可协议,这两个组织都不会去仔细分析。曾经这两个组织也都达成一致,有过一个协议符合其中一个组织的定义,但不符合另一个的要求。每当我试图找寻更多关于此事的细节,但得到的许可协议的名字却总不相同,但反正这些协议也不常见到,所以现在你可能用到的协议里面,"OSI-approved"和 "FSF-approved"就没有什么区别的了。 确实有大量可供选择的许可证。其中大多数我们这里不必讨论,因为他们通常是为了满足公司或个人的特定法律需求,不会适合你的项目。我们会限制为大多数常见的许可证;大多数情况下,你会从其中选择一个。 “可以做任何事情的”许可证 如果你能够接受你的项目代码会潜在的使用到私有程序中去,可以选择MIT/X-样式的许可证。这是一些最小许可证中最简单的一种,只保留署名版权(实际没有限制拷贝)并指明代码没有任何保证。细节见 GPL 如果你不希望你的代码在私有程序中使用,可以使用GNU的通用公共许可证(GNU General Public License, version 3 (https://www.gnu.org/licenses/gpl.html))。GPL可能是当世最广泛公认得自由软件许可证。在本质上是一个巨大的优势,因为许多潜在的用户和贡献者已经对此许可证十分熟悉,所以用户都不用花更多的时间去阅读和理解这个许可协议。更多细节看 If users interact with your code primarily over a network connection如果用户对你们代码的主要需求要联网才能实现—也就是说提供的软件是在线提供的话,而不是分发给每个用户在自己的机器上下载使用— 那么你们可以考虑使用GNU Affero GPL 代替GPL。这个AGPL就是在GPL的基础上添加了一句对在线访问目的的要求。可以参见 位于了解更多. 如何为你的软件应用许可证 一旦你选择了一个许可证,你就需要去应用它。 你需要做的第一件事就是在项目首页注明。你不必引入许可证的实际文本;只需要提供许可证的名称,并提供到完整许可证文本的链接。这告知公众你希望软件按照何种许可证发布,但是对于法律目的还不足够。这个软件本身必须包含许可证。 一个常见的做法是将许可证全文保存到一个叫做COPYING(或LICENSE)文件中,其中包含了许可证的全文,然后还要注意在每个源文件的开头,注明版权日期、所有者和许可证,以及何处可以找到版权全文。 这个模式也有许多变种,所以我们这里看一个实例。GNU的GPL说可以在每个源文件的开头放置如下的提醒: 或者LICENSE Copyright (C) <year> <name of author> This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 并不是说随程序收到的许可证拷贝在文件COPYING或者LICENSE中,而是它通常放置在那个地方(你可以在上面的声明中直接注明位置,但没有什么必要)。 一般来说,你在每个源文件放置的通告不会和上面这个完全一样,只需要其包含版权持有者和日期,以及版权的名称,并明确指明完全许可证的位置即可。基于版权的目的,每当文件被修改了,那么就需要记录下修改的日期。换句话说,如果一个文件在2008年、2009年和2013年被编辑过,那你就要写下“2008,2009,2013”—而不是“2008-2013”,因为该文件并非在这个区间里的每一年都被修改了。, 当然了,如果有钱的话,最好的方式还是请一名律师吧。 设置风格 我们已经覆盖了配置项目时的大多数一次性任务:选择一个许可证,安排初始的网站等等。但是开始一个新项目时最重要的方面是会变化的。选择一个邮件列表地址很容易;而保证讨论的内容不偏题且有效率则完全是另一回事情。如果项目经过多年的关闭,内部的开发,重新开始时开发过程将会改变,你需要准备开发者来应对这种变化。 第一步是最难的,因为未来管理的先例和预期都没有设置。正式的规则还没有带来项目的稳定性,而是由开发过程中共享的难以稳定的团体智慧带来。也许有已经写好的规则,但通常是通过难以预料的,不断进化的协议来引导项目。写好的规则不能定义其描述的项目文化,即使后来也是近似而已。 这里是如此解决问题的一些原因。成长和高转化率不会像一般人想象的那样损坏社会规范的积累。只要变化不要快,就有时间让新来者学会如何做事,在他们学会之后,他们自己就会来加强这种方式。考虑一下数世纪以来儿童歌曲的发展。现在孩子们演唱的歌曲和几百年前有大致相同的韵脚,即使现在的孩子从来没有生活在那个时代。小点的孩子听到大点的孩子唱歌,然后当他们长大了,他们又会在更小的孩子面前演唱。孩子不是故意参与这个传递程序,当然,这些歌曲的传承确实是因为有规律和重复的传递。自由软件项目不会以世纪(我们还不能知道)作为测量的时间刻度,但是变化和传递非常类似。转化率更快,不管怎样,必须以更活跃和慎重的传递投入来作为补偿。 人们通常会期望和寻找社会规范的事实,会成为这种努力的辅助。这也是人类的做法。在任何以共同努力统一的团队中,加入者都会凭直觉寻找可以将自己标记为团队一部分的行为。尽早设定先例的目标是让这些“组内”行为对于项目发生作用;一旦建立,多半会生生不息。 通过特定实例,你可以设置好的先例。这不必是一个完整的列表,但是通过尽早设置这样的协作情绪的方法,可以大大的帮助项目。从物理上讲,每个开发者都在自己的房间独立工作,但是你可以设法让他们感觉是在一个房间一起工作。他们这样的感觉越多,就会在项目上花费更多的时间。我选择了这些例子,因为这些实例来自Subversion项目(http://subversion.apache.org/),而我从一开始就参与并观察了这些实例。但是这不仅仅对Subversion有效;大多数开源项目中都会遇到类似的情形,这是开个好头的好机会。 避免私下讨论 即使你已经将项目公开,你和你的创始人也会经常希望通过私下讨论来解决困难的问题。这在项目的开始阶段尤其明显,因为此时需要做出许多重要的决定,而只有少量志愿者能够胜任。你会发现公开讨论的明显缺点:邮件对话本身的延迟性,需要保留足够的时间来达成一致,处理自以为是的幼稚的志愿者(每个项目都有;有些将来会成为明星贡献者,而有些会永远保持幼稚),也就是那些不能理解你为什么只希望解决问题X,而X明显是大问题Y的子集的人。秘密决定并使之成为既成事实,或者至少成为联合和有影响力的投票集团的坚实推荐,确实非常有吸引力。 不要这样做。 尽管公开讨论可能很笨重,但是从长远来看这样做更合适。私下里做出重要的决定就像是将贡献者排斥出项目一样。没有重要的志愿者会愿意呆在这样一个由秘密委员会做重要决定的环境里。此外,公开讨论也会从其副作用中获益,无论是多么短暂的技术问题,一经发起都会一直讨论下去: 讨论有助于训练和教育新开发者。你不知道有多少双眼睛在关注着讨论;即使大多数人不会参与,仍然可能有很多人在静静的跟踪,收集软件的信息。 讨论会训练如何向不熟悉软件的人们解释技术问题。这种技巧需要练习,你不能从已经知道你所知道的人那里获得这种练习。 之后,讨论和结论将会一直存放在公共归档中,可以保证以后的讨论不会回到同样的步骤中。见 最后,很有可能某个人会提出一个你从没想到过的好主意,给对话带来真正的贡献。很难说这有多大的可能;这仅仅由代码的复杂程度和需求的专业程度决定。但是如果允许我使用轶事作为证据,我会证明这样做比直觉所期望的结果更好。在Subversion项目,我们(创始人)相信我们面对的是一组深入而复杂的问题,为此我们痛苦思考了几个月,我们很明确的怀疑在新建立的邮件列表中的会有任何人做出真正的贡献。所以我们选择了一条比较懒惰的方式,开始通过私下邮件讨论技术想法,直到项目的一个观察者我们这里不是为了还债,而是实践我前面讲的说教:这位观察者的名字是Brian Behlendorf,他指出了除隐私原因以外,保持所有讨论公开的普遍重要性。嗅出了问题,并要求将讨论公开。眨了眨眼我们这样做了—后来的结果让我们十分惊讶,我们很快便获得了许多有见地的回复和建议。大多数情况下人们提供的想法都是我们从来没有想到的。结果是邮件列表中一下子多了许多非常英明的人;他们只是在等待正确的诱饵。可以肯定地是公开讨论比私下讨论会保持更长的时间,也能得到更多的产出,花费额外的时间是值得的。 我们不必把问题总结为:“团结就是力量”(我们已经见过许多更成功的团队),但可以确认的是有一些事情适于在团队中完成。首先是有了大量的审阅;其次是快速产生大量的想法。想法的质量由其所针对的思想决定,当然,在你用挑战性的问题刺激他们之前,你无法判断这些思考者是那种人。 当然,也有许多讨论必须在私下进行,通过此书我们会看到这种例子。但是我们有一个指导原则如果没有保持秘密的原因,那就公开进行。 要想使之发生,我们需要行动。仅仅保证自己所有的通告公开是不够的。你也需要劝说其他人放弃不必要的私下讨论。如果某个人尝试开始没有必要的私下讨论,你要义不容辞的立刻进行恰当的元讨论。在你将讨论成功的引入公开场所之前,不要对原始主题做出任何回复,或者去确定私下进行是否必须。如果你一贯如此,人们会很快会意,并开始首选公开论坛进行讨论。 防无礼于未然 从项目的一开始,你就应该保持论坛中粗鲁和无礼行为的零容忍。零容忍不是指技术上的实质强制。当有人侵犯其他用户,你不需要将其从邮件列表中删除,或因为其无礼的回复而收回其回复权限。 (理论上讲,可能最终你必须诉诸这类行动,但应该是其他方法失败之后才采用—这需要清晰的表述,而不应该是项目开始的情况。)零容忍指的仅仅是决不漏掉任何此类坏行为。例如,有人发布的技术回复中掺杂了对某一个项目开发者的个人偏好的攻击,首先你应该紧急回复来指明这种个人偏好的攻击,并指出作为技术问题本身,应该只包含技术内容。 不幸的是这并不很容易,更普遍的是,建设性的讨论演变为破坏性的论战。人们会在邮件里谈事情,而永远不会面对面谈论。讨论的主题只是放大了这种效果:在技术问题中,人们经常感觉对大多数问题有一个唯一的答案,而对此答案的异议只能被解释为无知或愚蠢。某人技术提议的愚蠢与某人本身的愚蠢不算太远。实际上,有时候很难说出技术争论和人身攻击从哪里开始,这也是激烈回复或惩罚不是好主意的一个原因。相反,当你发现此类事件发生,你应当回复来强调保持友善讨论的重要性,而不要指责任何人是故意为害。可惜这种“软规则”回复有点像幼儿园老师教导学生学习好的行为:
首先,请减少带有个人倾向的回复;例如,称J的安全层设计对“计算机安全基本原理的幼稚和无知”。这样说对错都有可能,但是无论何种情况,我们都无法进行讨论。J真心诚意地提出意见。如果存在Bug,请指出来,我们会进行修正并得到新的设计。我确定M对于J并无人身攻击,但是措辞是不合适的,我们会努力保持事务的建设性。 现在,对于这个建议。我认为M所说的是正确的...
因为此回复的不自然,会有显著的效果。如果你对于坏的行为保持一贯的行动,而不是要求攻击方进行道歉和承认,这样就让人们可以自由的冷静下来,而在下一次能够表现的更有礼貌一点—他们会的。 这样做能成功的诀窍是不要将元讨论作为主题。它必须放在一边,成为回复主要部分的简短序言。通过顺便提及指出“我们这里不是这么做的”,然后转移到真正的内容,这样你就给了人们一些可以回复的话题。如果有人抗议他们不应该受到你的责难,只需要拒绝讨论这个问题。除了不回复(如果你认为他们只是精力过剩,不需要回复),也可以说你为反应过度而道歉,而且在邮件中很难感到这种微妙之处,然后回到主题。绝不在任何时候要求一个人为不合适行为作出承认,无论是公开还是私下的。如果他们选择随自己的意愿进行道歉,那样很好,但是要求他们那么做只会导致怨恨。 总体目标是将好的礼节视为“团队内”的行为。这可以帮助项目,因为开发者会由于论战而流失(即使是他们喜爱和希望提供支持的项目)。你可能甚至不知道他们为什么离开;有些人可能一直潜伏在邮件列表,考虑到加入到项目需要的厚脸皮,就会决定放弃加入。保持论坛的友善是一个长期生存策略,在项目还比较小的时候,这很容易。一旦这成为了文化的一部分,你就不是唯一提升这种文化的人。所有人会一起维护。
行为准则 从这本书2006年出版以后的十年来,开源项目,特别是较大的项目,采用明确的行为准则(code of conduct)已经变得更加普遍。我觉得这是一个不错的趋势。随着开源项目最终变得更加多样化,行为准则的存在可以提醒参与者三思而后行,例如某种笑话是否会对某些人造成伤害。行为准则提醒参与者保证一个互相尊重和友好的环境是每个人的责任。 上网随便搜一下就能找到很多开源项目行为准则的例子,但最常用的可能还是这个https://contributor-covenant.org/这样做的好处就是:很多开发者本身就熟悉这个准则了,而且还省去了翻译的费用等等。 不过一个行为准则并不能解决人际交往的问题。甚至于,如果错误使用的话,可能还会造成其他问题。—总是能找到专门钻社会规则漏洞的人,他们会妨害这个社区而不是帮助它变得更好。(参见 位于 ),如果你不幸运的话,他们可能会出现在你的项目里。确保行为准则被合理正确的执行往往都是项目管理人员(人们愿意听他们的)的任务。(同样参见 位于 .) Some participants may genuinely disagree with the need to adopt a code at all, and argue against it on the grounds that it could do more harm than good. 有些参与者也许真的不认同确认一个准则的需求,甚至觉得那是弊大于利。即使你觉得他们是错的,你也必要保证他们能够陈述自己的观点而不会受到攻击。毕竟,不同意项目需要行为准则,不等价于—事实上,完全无关于—参与了违背行为准则的行为。有时候人们会混淆两者的概念,这个区别还是应该得到重视。这里有一个非常棒的帖子https://subfictional.com/2016/01/25/the-complex-reality-of-adopting-a-meaningful-code-of-conduct/ 由Christie Koehler写的,里面讨论了很多这些内容。 实践明显的代码评审 促进开发生产率的一个最好的办法就是让人们互相察看代码。需要一些技术基础设施来进行有效的支持—特别是提交邮件应该开启;更多细节见。提交邮件的作用就是每当有人提交了源代码的修改,就会发送一封包含日志信息和变更差异(见)的邮件。 代码评审是在代码来到时对提交邮件进行评审,寻找Bug和可能的改进的实践。无论如何,这是开源项目常见的做法。在更集中式的项目中,“代码评审”也也意味着许多人坐在一起,一起察看打印的源代码,寻找特定的问题和模式。 代码评审同时满足多个目标。这是开源世界的同级评审中最明显的一个例子,直接促进维护软件的质量。软件的每一个Bug都是提交进来的,而且没有被发现;因此,关注的眼睛越多,将会带入越少的Bug。但是代码评审也有非直接的目标:它确认了人们所真正关心的东西,因为很明显一个人不会去花时间评审他不关心的功能。当人们知道会有人花时间评价他的工作,他们就会倾尽全力。 评审必须是公开的。即使有时我与其他开发者坐在同一个物理房间,我们中的一个做出了提交,我们也尽量不在房间中进行口头评审,而是将其发送到开发邮件列表。所有人会从看到发生的评审获益。人们紧跟着评论,有时会在其中发现瑕疵,即使没有发现,这也会一直提醒他们评审是一个预期的,有规律的活动,就像刷盘子和割草坪。 需要一些技术上的机制来有效地进行变更审阅。特别要提到的是,设置提交通知非常有用。提交通知的效果是,每当有人提交更改到中央存储库时,会发出电子邮件或其他可订阅的通知,显示日志消息和差异(除非差异太大;参见,位于)。评论本身可能发生在邮件列表或Gerrit或GitHub"pull request"界面等评论工具中。参见 位于的详细说明。 案例研究 在Subversion项目,开始时并没有建立有规律的代码评审实践。无法保障所有的提交会得到评审,尽管如此,还是会有人在看到感兴趣的代码块时看一下修改。一些小Bug确实能够,也应该被发现。一个叫Greg Stein的开发者,从以前的工作知道代码评审的重要性,决定通过评审每个单独提交到源代码库的每一行来设立一个范例。每当有人提交,邮件列表就会紧跟着出现Greg的邮件,解剖这次提交,分析可能的问题,偶尔还会赞扬一下聪明的代码。很快,他就发现了其他人会略过而不会注意的Bug和非最优的代码实践。更深刻的是,他从没有抱怨他是唯一评审所有提交的人,尽管这样做占用了他很多时间,但是他确实一有机会就会盛赞代码评审。不久之后,其他人,包括我也开始了有规律的提交评审。 我们的动机是什么?不是Greg有意识的让我们为此感到羞愧。而是他已经证明代码评审是值得花费时间的方法,它的贡献与编写新的代码不相上下。一旦他证明了这一点,它就成为预期的行为,以至于如果一个提交者发现没有人对其提交有任何反应,他会感到担心,甚至会在列表中讯问是否有人愿意花时间为其评审。不久之后,Greg得到一个工作,他也没有更多时间为Subversion工作,结束了有规律的评审。但是之后,他的习惯深深影响了我们,似乎这样做是天经地义的。 从第一个提交就开始评审。差异评审中最容易检查出来的问题包括安全漏洞、内存泄露、注释不足或API文档问题、位偏移错误、调用/被调用不匹配以及其他在较小的上下文就能发现的问题。然而,即使这类未能将重复的模式抽象到一处的较大规模问题,在经过有规律的评审后也可以被定位出来,因为对以前差异的记忆提醒了对当前差异的评审。 不要担心你未能发现任何需要回复的内容,或者你不是很清楚代码的每个部分。通常几乎每一次提交都会要说什么事情;即使你没有发现任何事情可以提问,你还是可能发现一些事情可以对其称赞。最重要的是让每个提交者清楚,他们所做的事情都正在被关注和理解。当然,代码评审不能让程序员逃脱在提交之前评审和测试他们所做变更的责任;人们不应该依靠代码评审来捕捉本应该他自己捕捉的问题。 开放要从第一天开始 从第一天开始就将你的项目开源。项目以闭源方式运行的时间越长,以后开源就越困难。本节最初是一篇博文,http://archive.civiccommons.org/2011/01/be-open-from-day-one/index.html, 不过后来加到这里修改了不少。 从一开始就是开源并不意味着你的开发人员必须立即承担社区管理的额外责任。 人们常常认为“开源”意味着“陌生人用问题分散我们的注意力”,但这并其实是可选的—如果你觉得这对你的项目有所帮助的话,那才这样选,所以还是在你的掌握之中。从一开始就开源的话,就有很多不错的好处,而相反的,如果一个项目闭源时间越久,那就越难在日后开源了。 我认为下面可能是一个潜在的原因: 在项目的每一个阶段,程序员都面临一个选择:是做成兼容开源的模式呢?还是做成不兼容开源的呢?而每当他们选择了后者,那么这个项目就离开源可以说是越来越远了。 关键的是,他们有时候没办法就会选择后者—开发的压力就迫使他们往那边靠拢。修复测试人员不断报告的错误,或者完成客户刚刚添加到规范中的功能,所有这些对于程序员的压力相比于闭源开发都太大了。 此外,努力保持预算的程序员将不可避免地在某些地方偷工减料。用Ward Cunningham的话来说就是,他们会招致"technical debt" (https://en.wikipedia.org/wiki/Technical_debt),因为他们打算以后再说。 因此,当你需要开源的时候,你会突然发现下面这些事情: 特定客户的配置和密码出现在代码存储库; 从实时(和机密)信息构建的样本数据; 包含无法公开的敏感信息的错误报告; 代码中的评论表达了对客户最新紧急请求的“”过于诚实”的反应; 开发人员团队之间的通信档案,并不打算展示给陌生人的技术信息; 由于依赖库而导致的许可问题,其条款可能适用于内部部署(或者甚至不适用),但与开源分发不兼容; 以错误格式编写的文档(例如,您所在部门使用的专有内部Wiki),没有简单的翻译工具可用于将其格式化为适合公开发布的格式; 非可移植构建的依赖项,只有当你尝试将软件移出内部构建环境时才会发现原来不可移植; 存在一些Modularity violations每个人都知道有问题,但还没有时间去清理这些问题 (这列表可能还要补充。) 问题不仅仅在于清理工作; 他们有时还需要额外决策。例如,如果敏感材料过去被存入代码存储库,那么你的团队现在可以选择完全从历史修订中清除它,这样您就可以开源整个(脱敏)历史记录,或者只是清理最新的历史记录,然后再从这里开源(有时称为“top-skim”)。这两种方法没有对错—但这也是问题:因为你现在需要多做一个决定了 在某些项目中,在最终版本发布之前,会有多次这种决定,而且有时候决定还会有所反转。但选择的本身就是成本的一部分。 Waiting Just Creates an Exposure Event The other problem with opening up a developed codebase is that it creates a needlessly large exposure event. Whatever issues there may be in the code (modularity corner-cutting, security vulnerabilities, etc), they are all exposed to public scrutiny at once& nbsp;— the open-sourcing event becomes an opportunity for the technical blogosphere to pounce on the code and see what they can find. Contrast that with the scenario where development was done in the open from the beginning: code changes come in one at a time, so problems are handled as they come up (and are often caught sooner, since there are more eyeballs on the code). Because changes reach the public at a low, continuous rate of exposure, no one blames your development team for the occasional corner-cutting or flawed code checkin. Everyone's been there, after all; these tradeoffs are inevitable in real-world development. As long as the technical debt is properly recorded in "FIXME" comments and bug reports, and any security issues are addressed promptly, it's fine. Yet if those same issues were to appear suddenly all at once, unsympathetic observers may jump on the aggregate exposure in a way they never would have if the issues had come up piecemeal in the normal course of development. (These concerns apply even more strongly to government software projects; see in .) The good news is that these are all unforced errors. A project incurs little extra cost by avoiding them in the simplest way possible: by running in the open from Day One. "In the open" means the following things are publicly accessible, in standard formats, from the first day of the project: the code repository, bug tracker, design documents, user documentation, wiki, and developer discussion forums. It also means the code and documentation are placed under an open source license, of course. It also means your team's day-to-day work takes place in the publicly visible area. "In the open" does not have to mean: allowing strangers to check code into your repository (they're free to copy it into their own repository, if they want, and work with it there); allowing anyone to file bug reports in your tracker (you're free to choose your own QA process, and if allowing reports from strangers doesn't help you, you don't have to do it); reading and responding to every bug report filed, even if you do allow strangers to file; responding to every question people ask in the forums (even if you moderate them through); reviewing every patch or suggestion posted, when doing so may cost valuable development time; etc. One way to think of it is: you open source your code, not your time. The former resource is infinitely replicable; the latter is not, and you may protect it however you need to. You'll have to determine the point at which engaging with outside users and developers makes sense for your project. In the long run it usually does, and most of this book is about how to do it effectively. But the pace of engagement is always under your control. Developing in the open does not change this, it just ensures that everything done in the project is, by definition, done in a way that's compatible with being open source.
将一个之前封闭的项目开放 当然最好还是避免去做一个将闭源项目开源化的事,直接在一开始就开源吧!但如果你的项目已经是闭源的了,里面活跃的开发者们也都习惯了闭源开发环境,然后你又在准备使之开源,那就会有一些比较常见的问题可能会出现。提前准备好应对方法的话能帮你省下很多时间。 处理这些问题的方法都已经有套路了—而且 就能作为一个待做事项表。例如,如果您的代码依赖于不属于目标操作系统标准分发的专有库,则需要查找开源替换; 如果有机密内容—比方说,不可轻易更改的,不能公开的注释、密码或特定站点的配置信息,属于第三方的机密数据等— 在项目的版本控制历史中,您可能必须发布“top-skim”版本,即从您开源代码的那一刻起重新开始当前版本的版本历史记录; 等等。 但也存在社会性和管理上的问题,从长远来看,它们通常比这些可以机械工作解决的问题更重要。你必须确保每个在开发小组的人都能理解正要发生的重大变化—你必须设身处地的为他们着想。 想象一下他们面对的情形:以前,所有的代码和设计决定都是由一组程序员做出,他们对软件有差不多相等的熟悉程度,而且都是从同一个管理中接受相同的压力,而且清楚其他人的长处和弱点。现在你让他们将代码暴露给随机的陌生人监视,而他们只会根据代码形成判断,而不会考虑造成这种决定的商业压力。这些陌生人会询问很多问题,这些问题让已有的开发者发现无论如何为文档苦干,仍然不足(不可避免的)。最关键的是,这些新来者是未知的,未露面的实体。如果你的一个开发者已经感觉到他的技艺不够安全,想想一下当新来者指出他所写代码的Bug时的严重性,更严重的,在他的同事面前。除非你有一个拥有完美编码员的团队,这是不可避免的—实际上,对于每一个人开始都会发生这种情况。这不是因为他们不是好程序员;只是因为任何超过一定规模的程序都会有Bug,而同级评审可以发现一些此类Bug(见本章前面的)。而此时,新来者开始本身并没有受到同级评审的支配,因此他们在熟悉项目之前不能贡献代码。对你的开发者,感觉指责正在到来,绝不会离开。因此,要小心这些老手的人心散了。 防止发生这种情况的最佳方法是警告每个人即将发生的情况,告诉他们开始的不适是完全正常的,鼓励他们一切都会好起来的。有一些警告应该在私下发生,在项目开放以前。但是你也会发现如果在公共列表中提醒人们会有好处,告诉他们这是项目开发的新方式,需要一段时间来调整。你能做的最好的事情是通过实例进行引导。如果你看到你的开发者无法回答足够多的新手问题,那么只要告诉他们回答更多也于事无补。也许他们对于何种问题需要保证回复没有太好的感觉,或者他们对于如何排定代码工作和新的外部沟通交流负担的优先级没有感觉。让它们参与进来的方法是你自己参与进去。作为一个公开邮件列表,确保在那里回答一些问题。当你没有回答某个问题的技能时,要明确的交给能做的开发者—然后观察确保有回答或至少是一个回应。当然现在还是有长期开发者进行私下讨论的诱惑,因为他们一贯如此。请确定你已经订阅了可能发生问题的内部邮件列表,并且告知他们此类讨论应该立刻公开。 如果你想要一个新开放的项目能招纳不直接针对他们工作收费的开发者—在大部分成功的开源项目里,往往都有一些这种开发者—参见 阅读更多关于如何成功的在一个项目里同时拥有收费开发者和不收费开发者的讨论。 通告 一旦项目可以展示了—不必完美,只要能看—就可以将其通知给世界了。 这是一个比你想象中要简单的过程。第一步就是在你项目的首页设置一个公告,如同这里说的那样) 位于 。然后,在合适的论坛里发布通告。这有两种论坛:有各种新项目的通用论坛和只讨论特定主题的论坛(你项目可能会受到欢迎的那种)。 确保在你的公告里包含用户能在搜索引擎中搜到你的关键词。一个不错的测试就是,如果有人搜索“open source foo bar baz”,然后你的项目又提供这些,那它就应该出现在第一个结果页里 。(除非你有很多竞争者—但那是不可能的,因为你看了对吧? 截止到2017年年底,最好的发公告的综合型论坛大概是https://news.ycombinator.com/。尽管你可以在那边提交你的项目,也要注意需要有人点赞受到关注才能被显示在主页上。reddit论坛的开源分区 https://www.reddit.com/r/opensource/, https://www.reddit.com/r/programming/, 和https://www.reddit.com/r/software/都有类似的机制。如果能让你的项目出现在这些地方,确实很不错,但我也不知道如何提出具体的建议帮助你赢得竞争。还是靠你自己的判断,不要搞得太过(以至于像垃圾邮件了)。 你可能也会想在这里注册你的项目https://freshcode.club/,还有这里 http://openhub.net/,这个很像是自由软件项目和贡献者的全球数据库,虽然在某种程度上感觉有点杂乱。 最后,特定主题的论坛可能是你最感兴趣的地方了。如果你知道某个邮件列表或新闻组会对你的项目合题或感兴趣—你可能是其中的一员—,那么请在那里通告,但请注意,一个论坛只有一个通告,将人们引向项目本身的论坛,进行后续的讨论(通过设定Reply-to头)。这种发布一定要简短扼要,并且邮件的Subject一栏要清楚的表明这是一个新项目的发布公告: To: discuss@lists.example.org Subject: [ANN] Scanley全文索引项目 Reply-to: dev@scanley.org 这是关于Scanley项目的一次性公告,Scanley是一个包含丰富API的开源全 文索引和搜索引擎,主要为程序员提供对于大组文件的搜索服务。Scanley 现在是可运行的代码,正在进行活跃的开发,征集开发者和测试者。 主页: http://www.scanley.org/ 特性: - 查找纯文本、HTML和XML - 单词和短语查询 - (计划) 模糊匹配 - (计划) 增量更新索引 - (计划) 索引远程网站 前提条件: - Python 3.2或更高 - SQLite 3.8.1或更高 更多信息,请访问scanley.org。 谢谢, -J. Random (有关后续发布版本,以及项目其他事件的通告建议,请看。) 对自由软件世界是否应该以一个可执行的代码作为开始,以及在设计/讨论阶段就进行公开是否有益还存在着争议。我过去认为从一个可执行的代码开始是非常重要的因素,这是成功项目和玩具的重要区别,慎重的开发者只会加入有一定事实的软件。 但也有例外。在Subversion项目,我们从设计文档、一组核心的感兴趣和紧密联系的开发者、许多热闹的介绍和能运行的代码开始。完全出乎我的意料,项目从一开始就获得了活跃的参与者,当我们可以运行什么时,已经有不少志愿开发者已经深入参与进来。Subversion不是唯一的例子;Mozilla项目也是从不能运行的代码开始,现在成为了成功和流行的web浏览器。 面对这种证据,我必须回过头来看可运行代码是启动项目必要条件的断言。可运行程序仍然是成功的最重要基础,一个好的经验法则是直到可以运行再开始公开发布项目注意 公开发布你的项目可能在你开源了代码的很久以后。我的建议是考虑何时公开发布并不应该影响你将代码开源。—理想的情况下,你的项目应该从一开始就把代码开放给大家,而这个和你何时公开发布是互不影响的。参见 了解更多。然而,有一些环境下,尽早通告是有意义的。我想这时起码要有完成良好的设计文档,或其他代码框架—当然,这也许需要根据公共反馈调整,但是要有一些实际的东西,比好的意图更确切地东西,让人们可以动动牙齿。 无论你何时通告,不要指望立刻有一大堆志愿者会到来。通常情况下,通告的结果是得到很少随意的询问,以及一些人加入你的邮件列表,除此之外,一切如常。但随着时间的流逝,你会逐渐发现代码贡献者和用户参与的增加。通告仅仅是播下种子。消息的传递需要很长时间。如果项目持续回报参与者,这个新闻就会传播,因为人们喜欢分享他们所发现的好东西。如果一切都好,指数级交流网络的动力会慢慢将项目改变为复杂的社区,你不必再知道每个人的名字,也不必跟踪每一次对话。下一章我们将讨论在这个环境下如何工作。