Пока мы описали одноразовые задачи, которые вы решаете во время подготовки проекта: выбор лицензии, размещение начального вебсайта, и т.д. Но самые важные аспекты начинания нового проекта являются динамическими. Выбор адреса списка рассылки прост; обеспечение того, что разговоры в листе рассылки остаются в границах темы и продуктивны является совсем другим вопросом. Если проект становится открытым после нескольких лет закрытой, внутренней разработки, его процессы разработки изменятся и вам будет нужно подготовить уже существующих разработчиков к этому изменению.
Первые шаги — самые сложные, потому что еще не определены предварительные условия и ожидаемое в будущем поведение. Стабильность внутри проекта создается не с помощью формальных соглашений, а с помощью принятой всеми и трудноопределимой коллективной мудрости, которая формируется со временем. Часто встречаются и записанные правила, но они являются, в сущности, дистилляцией нематериальных, неизменно присутствующих соглашений, которые направляют проект на самом деле. Записанные правила не столько определяют культуру проекта, сколько описывают ее, и даже описывают только приблизительно.
Существует несколько причин того, что работа строится именно так. Рост и высокая текучесть кадров не столь разрушительны для накопления поведенческих норм, как можно было бы подумать. Пока изменения не происходят слишком быстро, для вновь прибывших есть время узнать, как все сделано, и после того, как они узнают, они сами будут помогать укреплению этого стиля. Посмотрите, как детские песни переживают столетия. И сегодня есть дети, напевающие примерно те же самые рифмы, что и дети сотни лет назад, даже при том, что сейчас нет в живых ни одного ребенка, жившего тогда. Младшие дети слышат песни, спетые старшими, и когда они становятся старшими, они в свою очередь, споют их перед другими младшими. Конечно, дети не участвуют в сознательной программе по передаче, но причина, по которой песни выживают, тем не менее, в том, что они передаются регулярно и многократно. Временные рамки проектов свободного программного обеспечения не могут быть измерены столетиями (мы еще об этом не знаем), но движущие силы передачи во многом аналогичны. Степень текучести кадров, однако, выше и должна быть компенсирована за счет более активных и тщательно спланированных усилий по передаче.
Это усилие поддерживается тем фактом, что, обычно, люди склонны к ожиданию и поиску социальных норм. Так уж устроены люди. В любой группе, объединенной общим делом, люди, присоединяющиеся к ней, инстинктивно ищут модели поведения, которые сделают их частью группы. Целью создания прецедентов в ранний период является установление этих "внутри-групповых" моделей поведения, которые будут полезны для проекта; установленные однажды, они будут в значительной степени жить сами по себе.
Далее следует несколько конкретных примеров того, что вы можете сделать, чтобы создать хорошие прецеденты. Они не представляют собой исчерпывающий список, это просто иллюстрация мысли о том, что установление духа сотрудничества на ранней стадии чрезвычайно помогает проекту. Физически, каждый разработчик может работать в комнате сам по себе в одиночестве, но вы можете многое сделать, чтобы дать им почувствовать, будто все они работают вместе в одной комнате. Чем больше они будут себя так чувствовать, тем больше времени они захотят посвятить проекту. Я выбрал именно эти примеры, потому что они всплыли на проекте Subversion (http://subversion.tigris.org/), в котором я учавствовал и который наблюдал с самого начала. Но они верны не только для Subversion; подобные ситуации возникнут на большинстве открытых проектов, и они должны быть рассмотрены как возможность встать с той ноги.
Даже после того, как вы сделали проект общим, вы и другие основатели, будете частенько хотеть, разрешить трудные вопросы в процессе закрытого обсуждения в своем внутреннем круге. Это особенно верно в начале проекта, когда нужно принять очень много важных решений, и, обычно, мало добровольцев достаточно квалифицированы, чтобы их принять. Все очевидные недостатки обсуждения с помощью публичного листа рассылки будут ясно вырисовываться перед вами: задержка,как неотъемлемая часть разговоров по электронной почте, потребность оставить достаточное количество времени для согласования, споры с наивными добровольцами, которые думают, что понимают все проблемы, но на самом деле не понимают (такие есть в каждом проекте; иногда это лучшие программисты будущего года, иногда они остаются наивными навсегда), кто-то, кто не может понять, почему вы хотите решить только задачу X, в то время как очевидно, что это подмножество большей проблемы Y и так далее. Искушение принять решения за закрытыми дверьми и представить их как faits accomplis (свершившиеся факты) , или, по крайней мере, как прямые рекомендации объединенного и влиятельного большинства, вместо всего этого, будет очень большим.
Не делайте этого
Какими медленными и тягостными ни были публичные обсуждения, они почти всегда предпочтительнее в конечном итоге. Принятие важных решений частным образом похоже на распыление репеллента от участников на вашем проекте. Никакой серьезный доброволец не захотел бы долгое время слоняться поблизости в окружении, где тайный совет принимает все важные решения. Кроме того, у общественного обсуждения есть благотворные побочные эффекты, которые распространятся далеко за рамки любого эфемерного технического вопроса, который был спорным моментом:
Обсуждение поможет познакомить с системой и обучить новых разработчиков. Вы никогда не знаете, сколько глаз следит за беседой; даже если большая часть людей не принимают непосредственного участия, многие могут просто следить, собирая информацию о программе.
Обсуждение научит вас искусству объяснения технических вопросов людям, не так хорошо разбирающимся в программе, как вы. Этот навык требует тренировки, а вы не сможете тренироваться, разговаривая с людьми, которые уже знают то, что знаете вы.
Дискуссия и ее результаты будут всегда доступны в публичных архивах, позволяя в последующих обсуждениях не ходить по своим собсвенным следам. Смотрите «Conspicuous Use of Archives» в Глава 6, Communications.
Наконец, существует вероятность того, что кто-то из списка сможет сделать ценный вклад в беседу, выступив с идеей, которую вы никогда и не ожидали. Невозможно предсказать, насколько такое событие вероятно; это зависит лишь от сложности кода и требуемой степени специализации. Но если история из жизни может быть дозволена в качестве доказательства, я поставил бы на то, что это более вероятно, чем можно было бы интуитивно ожидать. В проекте Subversion мы (основатели) полагали, что оказались перед большим и сложным набором проблем, о которых мы интенсивно размышляли в течение нескольких месяцев, и мы искренне сомневались, что кто-либо из недавно созданного списка рассылки, способен реально посодействовать в обсуждении. Таким образом, мы выбрали ленивый путь и стали пинать туда-сюда некоторые технические решения в частной переписке, до того момента, когда ответсвенный за проект [10]понял куда дует ветер и попросил перенести дискуссию в общий доступ. Прикрыв глаза мы это сделали — и были ошеломлены числом проницательных комментариев и предложений, которые быстро последовали. Во многих случаях люди предлагали решения, которые даже не приходили нам в голову. Оказалось, что в этом списке нашлось некоторое количество очень умных людей; они лишь ждали нужной наживки. Да, в действительности последующие обсуждения заняли больше времени, чем они заняли бы, если бы мы оставили дискуссию закрытой, но они были настолько более производительными, что это стоило дополнительного времени.
Не углубляясь в обобщения, на которые можно махнуть рукой, типа "группа всегда умнее индивида" (все мы встречали достаточно групп, чтобы знать лучше), нужно признать, что есть определенные виды деятельности, в которых группы оказываются на высоте. Основательная экспертная оценка кода является одной из них; высказывание большого количества идей в короткое время - другой. Качество идей, естественно, зависит от качества думающего, взявшегося за них, но вы не узнаете, что за мыслители находятся рядом, до тех пор пока не стимулируете их сложной задачей.
Естественно, есть некоторые вопросы, которые должны обсуждаться конфиденциально; на протяжении этой книги мы увидим такие примеры. Но основополагающим принципом всегда должно быть:Если нет причин для того, чтобы вопрос обсуждался в частном порядке, он должен обсуждаться открыто.
Чтобы поставить дело именно так, необходимо над этим работать. Недостаточно просто проверять, что все Ваши собственные письма идут в общий список рассылки. Вам также нужно перенести в этот список рассылки разговоры других людей, для которых конфиденциальность является излишней. Если кто-то пытается начать закрытое обсуждение, и нет никакой причины для его закрытости, то именно вы ответственны за немедленное открытие соответствующего мета-обсуждение. Даже не комментируйте начальную тему, пока вы или успешно не направили разговор в общесвенно доступное русло, или не пришли к выводу, что конфиденциальность действительно была необходима. Если вы последовательно будете поступать именно так, то люди уловят смысл довольно быстро и начнут использовать общественные форумы по умолчанию.
С самого начала существования вашего проекта в качестве общедоступного, вы должны поддерживать политику нулевого допуска в отношении грубого или оскорбительного поведения на его форумах. Нулевой допуск не означает технического принуждения как такового. Вам не нужно удалять людей из списка адресатов рассылки, когда они грубят другим подписчикам, или лишать их возможности вносить свой код, потому что они пишут уничижительные комментарии. (В теории Вам, возможно, в конечном счете придется прибегнуть к подобным действиям, но только после того, как любые другие способы не дадут результата— чего не может быть в начале проекта по определению). Нулевой допуск просто означает, что вы никогда не позволяете плохому поведению проскользнуть незамеченным. Например, когда кто-то размещает комментарий технического плана вперемешку с ad hominem высказыванием в адрес какого-то другого разработчика на проекте, ваш ответ обязательно должен быть в первую очередь, направлен на высказывания ad hominem как на отдельную проблему саму по себе, и только затем переходить к технической части.
К сожалению очень легко, и это слишком типично, что конструктивные обсуждения скатываются в перебранки. В электронной почте люди говорят то, что они никогда не сказали бы лицом к лицу. Темы дискуссий только усиливают этот эффект: в технических вопросах люди часто подразумевают, что есть один единственный правильный ответ на большинство вопросов, и несоответствие этому ответу может быть объяснено лишь незнанием или глупостью. От определения чьего-то технического решения как глупого, недалеко и до определения как глупого и самого человека. Фактически, в большинстве случаев, сложно определить, в какой момент технические споры уходят в сторону и начинается нападение на личность, что и есть та причина, по которой решительные ответы или наказания не являются хорошей мыслью. Вместо этого, когда Вы думаете, что видите, как это происходит, пошлите сообщение, которое подчеркивает важность сохранения дружественного тона в обсуждении, не обвиняя никого в том, что он преднамеренно язвит. Подобные сообщения "Хороших Полицейских" в действительности имеют неудачную тенденцию звучать как речь воспитателя детского сада, читающего классу лекции о хорошем поведении:
Сначала,пожалуйста, давайте откажемся от (возможных) комментариев связанных с личностью; например, называть разаработанную Джеем архитектуру слоя безопасности "наивной и не отвечающей основным принципам компьютерной безопасности". Это может быть справедливо или нет, но в любом случае, такое обсуждение невозвомжно. Джей предложил свое решение по доброй воле. Если у него есть недостатки, укажите на них и мы их исправим или спроектируем новую архитектуру. Я уверен что Мей не хотел оскорбить лично Джея, но высказывание было неудачным, а мы пытаемся вести здесь конструктивный диалог.
Теперь, собственно о предложении. Я думаю Мэй был прав говоря, что...
Как бы искусственно не звучали такие ответыв, они дают заметный результат. Если Вы последовательно искореняете плохое поведение, но не требуете извинений или осознания ошибки от виновной стороны, то вы оставляете людям возможность остыть и показать их лучшую сторону, ведя себя более прилично в следующий раз—и они сделают именно так. Один из секретов успешности таких действий—никогда не делать это дополнительное обсуждение основной темой. Оно должно всегда быть несколько в стороне, вроде краткого предисловия к основной части вашего ответа. Укажите мимоходом, что "мы здесь так не делаем", но затем переходите к настоящему существу вопроса, так, чтобы вы дали людям конкретную тему, на которую надо ответить. Если кто-то возражает, что они не заслуживали вашего упрека, просто отказывайтесь быть вовлеченными в спор на эту тему. Также не отвечайте (если вы думаете, что они только спускают пар и не требуют ответа), или скажите, что вы сожалеете о том, что, наверное, слишком остро реагировали и что трудно различить нюансы в электронной почте, а затем возвращайтесь к основной теме. Никогда, никогда не настаивайте на признании кем-то вины, перед сообществом или перед самим собой, в том, что они вели себя неправильно. Если они по собственной воле захотят принести извинения, это великолепно, но требование такого признания только вызовет негодование.
The overall goal is to make good etiquette be seen as one of the "in-group" behaviors. This helps the project, because developers can be driven away (even from projects they like and want to support) by flame wars. You may not even know that they were driven away; someone might lurk on the mailing list, see that it takes a thick skin to participate in the project, and decide against getting involved at all. Keeping forums friendly is a long-term survival strategy, and it's easier to do when the project is still small. Once it's part of the culture, you won't have to be the only person promoting it. It will be maintained by everyone.
One of the best ways to foster a productive development community is to get people looking at each others' code. Some technical infrastructure is required to do this effectively—in particular, commit emails must be turned on; see «Commit emails» for more details. The effect of commit emails is that every time someone commits a change to the source code, an email goes out showing the log message and diffs for the change (see diff, in «Version Control Vocabulary»). Code review is the practice of reviewing commit emails as they come in, looking for bugs and possible improvements.[11]
Code review serves several purposes simultaneously. It's the most obvious example of peer review in the open source world, and directly helps to maintain software quality. Every bug that ships in a piece of software got there by being committed and not detected; therefore, the more eyes watch commits, the fewer bugs will ship. But code review also serves an indirect purpose: it confirms to people that what they do matters, because one obviously wouldn't take time to review a commit unless one cared about its effect. People do their best work when they know that others will take the time to evaluate it.
Reviews should be public. Even on occasions when I have been sitting in the same physical room with developers, and one of us has made a commit, we take care not to do the review verbally in the room, but to send it to the development mailing list instead. Everyone benefits from seeing the review happen. People follow the commentary and sometimes find flaws in it, and even when they don't, it still reminds them that review is an expected, regular activity, like washing the dishes or mowing the lawn.
In the Subversion project, we did not at first make a regular practice of code review. There was no guarantee that every commit would be reviewed, though one might sometimes look over a change if one was particularly interested in that area of the code. Bugs slipped in that really could and should have been caught. A developer named Greg Stein, who knew the value of code review from past work, decided that he was going to set an example by reviewing every line of every single commit that went into the code repository. Each commit anyone made was soon followed by an email to the developer's list from Greg, dissecting the commit, analyzing possible problems, and occasionally praising a clever bit of code. Right away, he was catching bugs and non-optimal coding practices that would otherwise have slipped by without ever being noticed. Pointedly, he never complained about being the only person reviewing every commit, even though it took a fair amount of his time, but he did sing the praises of code review whenever he had the chance. Pretty soon, other people, myself included, started reviewing commits regularly too. What was our motivation? It wasn't that Greg had consciously shamed us into it. But he had proven that reviewing code was a valuable way to spend time, and that one could contribute as much to the project by reviewing others' changes as by writing new code. Once he demonstrated that, it became expected behavior, to the point where any commit that didn't get some reaction would cause the committer to worry, and even ask on the list whether anyone had had a chance to review it yet. Later, Greg got a job that didn't leave him as much time for Subversion, and had to stop doing regular reviews. But by then, the habit was so ingrained for the rest of us as to seem that it had been going on since time immemorial.
Start doing reviews from very first commit. The sorts of problems that are easiest to catch by reviewing diffs are security vulnerabilities, memory leaks, insufficient comments or API documentation, off-by-one errors, caller/callee discipline mismatches, and other problems that require a minimum of surrounding context to spot. However, even larger-scale issues such as failure to abstract repeated patterns to a single location become spottable after one has been doing reviews regularly, because the memory of past diffs informs the review of present diffs.
Don't worry that you might not find anything to comment on, or that you don't know enough about every area of the code. There will usually be something to say about almost every commit; even where you don't find anything to question, you may find something to praise. The important thing is to make it clear to every committer that what they do is seen and understood. Of course, code review does not absolve programmers of the responsibility to review and test their changes before committing; no one should depend on code review to catch things he ought to have caught on his own.
If you're opening up an existing project, one that already has active developers accustomed to working in a closed-source environment, make sure everyone understands that a big change is coming—and make sure that you understand how it's going to feel from their point of view.
Try to imagine how the situation looks to them: formerly, all code and design decisions were made with a group of other programmers who knew the software more or less equally well, who all received the same pressures from the same management, and who all know each others' strengths and weaknesses. Now you're asking them to expose their code to the scrutiny of random strangers, who will form judgements based only on the code, with no awareness of what business pressures may have forced certain decisions. These strangers will ask lots of questions, questions that jolt the existing developers into realizing that the documentation they slaved so hard over is still inadequate (this is inevitable). To top it all off, the newcomers are unknown, faceless entities. If one of your developers already feels insecure about his skills, imagine how that will be exacerbated when newcomers point out flaws in code he wrote, and worse, do so in front of his colleagues. Unless you have a team of perfect coders, this is unavoidable—in fact, it will probably happen to all of them at first. This is not because they're bad programmers; it's just that any program above a certain size has bugs, and peer review will spot some of those bugs (see «Practice Conspicuous Code Review» earlier in this chapter). At the same time, the newcomers themselves won't be subject to much peer review at first, since they can't contribute code until they're more familiar with the project. To your developers, it may feel like all the criticism is incoming, never outgoing. Thus, there is the danger of a siege mentality taking hold among the old hands.
The best way to prevent this is to warn everyone about what's coming, explain it, tell them that the initial discomfort is perfectly normal, and reassure them that it's going to get better. Some of these warnings should take place privately, before the project is opened. But you may also find it helpful to remind people on the public lists that this is a new way of development for the project, and that it will take some time to adjust. The very best thing you can do is lead by example. If you don't see your developers answering enough newbie questions, then just telling them to answer more isn't going to help. They may not have a good sense of what warrants a response and what doesn't yet, or it could be that they don't have a feel for how to prioritize coding work against the new burden of external communications. The way to get them to participate is to participate yourself. Be on the public mailing lists, and make sure to answer some questions there. When you don't have the expertise to field a question, then visibly hand it off to a developer who does—and watch to make sure he follows up with an answer, or at least a response. It will naturally be tempting for the longtime developers to lapse into private discussions, since that's what they're used to. Make sure you're subscribed to the internal mailing lists on which this might happen, so you can ask that such discussions be moved to the public lists right away.
There are other, longer-term concerns with opening up formerly closed projects. Глава 5, Money explores techniques for mixing paid and unpaid developers successfully, and Глава 9, Licenses, Copyrights, and Patents discusses the necessity of legal diligence when opening up a private code base that may contain software written or "owned" by other parties.
[10] Мы еще не дошли до раздела о доверии, но чтобы показать на практике то, что я буду в дальнейшем проповедовать: имя ответсвенного было Брайен Бехлендорф, и именно он указал на общую значимость нахождения всех обсуждений в общем доступе, если только не возникнет особой нужды в частном разговоре.
[11] This is how code review is usually done in open source projects, at any rate. In more centralized projects, "code review" can also mean multiple people sitting down together and going over printouts of source code, looking for specific problems and patterns.