Сначала прочитайте Руководство для новых разработчиков .
Основные рекомендации и стиль кодирования
Большая часть нижеследующего должна быть очевидной для любого, кто работал над открытым исходным кодом или в коммерческой среде программирования. Следующее применимо в основном к основной ветке разработки i2p.i2p. Руководства для других веток, плагинов и внешних приложений могут существенно отличаться; проконсультируйтесь с соответствующим разработчиком для получения рекомендаций.
Сообщество
- Пожалуйста, не просто пишите код. Если можете, участвуйте в других связанных с разработкой активностях, включая: обсуждения разработки и поддержку на IRC и i2pforum.i2p; тестирование; сообщения об ошибках и ответы на них; документацию; проверку кода; и т.д.
- Активные разработчики должны периодически присутствовать на IRC
#i2p-dev. Следите за текущим циклом релизов. Придерживайтесь контрольных точек релиза, таких как заморозка функциональности, заморозка тегов и крайний срок регистрации изменений для релиза.
Цикл релизов
Обычный цикл релиза составляет 10–16 недель, четыре релиза в год. Ниже приведены приблизительные сроки в типичном 13-недельном цикле. Фактические сроки для каждого релиза устанавливаются менеджером релиза после консультации со всей командой.
- 1–2 дня после предыдущего релиза: Разрешены коммиты в trunk.
- 2–3 недели после предыдущего релиза: Крайний срок для переноса крупных изменений из других веток в trunk.
- 4–5 недель до релиза: Крайний срок для запроса новых ссылок на домашней странице.
- 3–4 недели до релиза: Заморозка функциональности. Крайний срок для крупных новых функций.
- 2–3 недели до релиза: Провести собрание проекта для рассмотрения запросов на новые ссылки на домашней странице, если таковые имеются.
- 10–14 дней до релиза: Заморозка строк. Больше никаких изменений в переведённых (помеченных) строках. Отправить строки на Transifex, объявить крайний срок перевода на Transifex.
- 10–14 дней до релиза: Крайний срок функциональности. После этого времени только исправления ошибок. Никаких новых функций, рефакторинга или очистки кода.
- 3–4 дня до релиза: Крайний срок перевода. Получить переводы из Transifex и зафиксировать.
- 3–4 дня до релиза: Крайний срок коммитов. Никаких коммитов после этого времени без разрешения сборщика релиза.
- За несколько часов до релиза: Крайний срок проверки кода.
Git
- Имейте базовое понимание распределенных систем управления версиями, даже если вы раньше не использовали git. Попросите помощи, если она вам нужна. После отправки коммиты остаются навсегда; отмены не существует. Пожалуйста, будьте осторожны. Если вы не использовали git раньше, начните с малого. Зафиксируйте несколько небольших изменений и посмотрите, как это работает.
- Тестируйте свои изменения перед их фиксацией. Если вы предпочитаете модель разработки «сначала фиксация, потом тестирование», используйте собственную ветку разработки в своём аккаунте и создайте MR после завершения работы. Не ломайте сборку. Не вызывайте регрессий. Если это всё же произошло (такое случается), пожалуйста, не исчезайте надолго после отправки своих изменений.
- Если ваше изменение нетривиально, или вы хотите, чтобы люди его протестировали и вам нужны качественные отчёты о тестировании, чтобы узнать, было ли ваше изменение протестировано или нет, добавьте комментарий о фиксации в
history.txtи увеличьте номер ревизии сборки вRouterVersion.java. - Не фиксируйте крупные изменения в основной ветке i2p.i2p в конце цикла релиза. Если проект займёт у вас больше пары дней, создайте собственную ветку в git в своём аккаунте и ведите разработку там, чтобы не блокировать релизы.
- Для больших изменений (как правило, более 100 строк или затрагивающих более трёх файлов) зафиксируйте их в новой ветке в своём аккаунте GitLab, создайте MR и назначьте рецензента. Назначьте MR на себя. Объедините MR самостоятельно после одобрения рецензентом.
- Не создавайте WIP-ветки в основном аккаунте I2P_Developers (за исключением i2p.www). WIP должен находиться в вашем собственном аккаунте. Когда работа завершена, создайте MR. Единственными ветками в основном аккаунте должны быть ветки для настоящих форков, например, для точечного релиза.
- Ведите разработку прозрачно и с учётом сообщества. Фиксируйте часто. Фиксируйте или объединяйте в основную ветку так часто, как это возможно, с учётом приведённых выше рекомендаций. Если вы работаете над большим проектом в своей собственной ветке/аккаунте, дайте людям знать, чтобы они могли следить за процессом и проводить ревью/тестирование/комментирование.
Стиль кодирования
- Стиль кодирования в большей части кода — 4 пробела для отступов. Не используйте табуляцию. Не переформатируйте код. Если ваша IDE или редактор хочет всё переформатировать, возьмите это под контроль. В некоторых местах стиль кодирования отличается. Используйте здравый смысл. Имитируйте стиль в файле, который вы изменяете.
- Все новые публичные классы и методы уровня пакета требуют Javadocs. Добавьте
@sinceномер-релиза. Javadocs для новых приватных методов желательны. - Для любых добавленных Javadocs не должно быть ошибок или предупреждений doclint. Запустите
ant javadocс Oracle Java 14 или выше для проверки. Все параметры должны иметь строки@param, все не-void методы должны иметь строки@return, все объявленные исключения должны иметь строки@throws, и никаких HTML ошибок. - Классы в
core/(i2p.jar) и части i2ptunnel являются частью нашего официального API. Существует несколько внешних плагинов и других приложений, которые полагаются на этот API. Будьте осторожны и не вносите изменения, нарушающие совместимость. Не добавляйте методы в API, если они не имеют общей полезности. Javadocs для методов API должны быть ясными и полными. Если вы добавляете или изменяете API, также обновите документацию на веб-сайте (ветка i2p.www). - Помечайте строки для перевода там, где это уместно, что справедливо для всех строк пользовательского интерфейса. Не изменяйте существующие помеченные строки без крайней необходимости, так как это нарушит существующие переводы. Не добавляйте и не изменяйте помеченные строки после заморозки тегов в цикле релиза, чтобы у переводчиков была возможность обновиться перед релизом.
- Используйте дженерики и классы для параллельных вычислений, где это возможно. I2P — это высоко многопоточное приложение.
- Ознакомьтесь с распространёнными Java-ловушками, которые обнаруживаются FindBugs/SpotBugs. Запустите
ant findbugs, чтобы узнать больше. - Java 8 требуется для сборки и запуска I2P начиная с релиза 0.9.47. Не используйте классы или методы Java 7 или 8 во встроенных подсистемах: addressbook, core, i2ptunnel.jar (не-UI), mstreaming, router, routerconsole (только news), streaming. Эти подсистемы используются Android и встроенными приложениями, которым требуется только Java 6. Все классы должны быть доступны в Android API 14. Языковые функции Java 7 допустимы в этих подсистемах, если они поддерживаются текущей версией Android SDK и компилируются в код, совместимый с Java 6.
- Try‑with‑resources нельзя использовать во встроенных подсистемах, так как это требует
java.lang.AutoCloseableв runtime, а это недоступно до Android API 19 (KitKat 4.4). - Пакет
java.nio.fileнельзя использовать во встроенных подсистемах, так как он недоступен до Android API 26 (Oreo 8). - Помимо указанных выше ограничений, классы, методы и конструкции Java 8 могут использоваться только в следующих подсистемах: BOB, desktopgui, i2psnark, i2ptunnel.war (UI), jetty‑i2p.jar, jsonrpc, routerconsole (кроме news), SAM, susidns, susimail, systray.
- Авторы плагинов могут требовать любую минимальную версию Java через файл
plugin.config. - Явно преобразовывайте между примитивными типами и классами; не полагайтесь на автоупаковку/распаковку.
- Не используйте
URL. ИспользуйтеURI. - Не ловите
Exception. ЛовитеRuntimeExceptionи проверяемые исключения по отдельности. - Не используйте
String.getBytes()без аргумента кодировки UTF‑8. Вы также можете использоватьDataHelper.getUTF8()илиDataHelper.getASCII(). - Всегда указывайте кодировку UTF‑8 при чтении или записи файлов. Утилиты
DataHelperмогут быть полезны. - Всегда указывайте локаль (например,
Locale.US) при использованииString.toLowerCase()илиString.toUpperCase(). Не используйтеString.equalsIgnoreCase(), так как локаль не может быть указана. - Не используйте
String.split(). ИспользуйтеDataHelper.split(). - Не добавляйте код для форматирования дат и времени. Используйте
DataHelper.formatDate()иDataHelper.formatTime(). - Убедитесь, что
InputStreamы иOutputStreamы закрываются в блоках finally. - Используйте
{}для всех блоковforиwhile, даже если это только одна строка. Если вы используете{}для блокаif,elseилиif-else, используйте их для всех блоков. Помещайте} else {на одну строку. - Указывайте поля как
finalвезде, где это возможно. - Не храните
I2PAppContext,RouterContext,Logили любые другие ссылки на router или контекстные элементы в статических полях. - Не запускайте потоки в конструкторах. Используйте
I2PAppThreadвместоThread.
Логирование
Следующие рекомендации применяются к router, веб-приложениям и всем плагинам.
- Для любых сообщений, не отображаемых на уровне журналирования по умолчанию (WARN, INFO и DEBUG), если сообщение не является статической строкой (без конкатенации), всегда используйте
log.shouldWarn(),log.shouldInfo()илиlog.shouldDebug()перед вызовом журналирования, чтобы избежать ненужного создания объектов. - Сообщения журнала, которые могут отображаться на уровне журналирования по умолчанию (ERROR, CRIT и
logAlways()), должны быть краткими, понятными и доступными для нетехнического пользователя. Это включает текст причины исключения, который также может отображаться. Рассмотрите возможность перевода, если ошибка может произойти с высокой вероятностью (например, при ошибках отправки формы). В остальных случаях перевод не обязателен, но может быть полезно найти и повторно использовать строку, которая уже помечена для перевода в другом месте. - Сообщения журнала, не отображаемые на уровне журналирования по умолчанию (WARN, INFO и DEBUG), предназначены для использования разработчиками и не имеют вышеуказанных требований. Однако сообщения WARN доступны во вкладке журнала Android и могут помочь пользователям в отладке проблем, поэтому проявляйте осторожность и с сообщениями WARN.
- Сообщения журнала INFO и DEBUG следует использовать умеренно, особенно в часто выполняемых участках кода. Хотя они полезны во время разработки, рассмотрите возможность их удаления или закомментирования после завершения тестирования.
- Не записывайте сообщения в stdout или stderr (журнал wrapper).
Лицензии
- Добавляйте в репозиторий только код, который вы написали самостоятельно. Перед добавлением любого кода или библиотечных JAR-файлов из внешних источников обоснуйте необходимость этого, убедитесь в совместимости лицензии и получите одобрение от менеджера релиза.
- Если вы получили одобрение на добавление внешнего кода или JAR-файлов, и бинарные файлы доступны в каком-либо пакете Debian или Ubuntu, вы должны реализовать опции сборки и упаковки для использования внешнего пакета. Контрольный список файлов для изменения:
build.properties,build.xml,debian/control,debian/i2p-router.install,debian/i2p-router.links,debian/rules,sub-build.xml. - Для любых изображений, добавляемых из внешних источников, вы обязаны сначала проверить совместимость лицензии. Укажите информацию о лицензии и источнике в комментарии к коммиту.
Ошибки
- Управление issues (задачами) — это работа каждого; пожалуйста, помогайте. Отслеживайте GitLab на предмет issues, с которыми вы можете помочь. Комментируйте, исправляйте и закрывайте issues, если можете.
- Новым разработчикам следует начинать с исправления issues. Когда у вас есть исправление, прикрепите свой патч к issue и добавьте ключевое слово
review-needed. Не закрывайте issue, пока оно не будет успешно проверено и вы не зафиксируете свои изменения. После того как вы проделаете это гладко для пары тикетов, вы можете следовать обычной процедуре, описанной выше. - Закрывайте issue, когда считаете, что исправили его. У нас нет тестового отдела для проверки и закрытия тикетов. Если вы не уверены, что исправили его, закройте его и добавьте примечание: “Думаю, я это исправил, пожалуйста, протестируйте и переоткройте, если всё ещё сломано”. Добавьте комментарий с номером dev build или ревизии и установите milestone (веху) на следующий релиз.