Недавно узнал, что существуют конкурсы Open Source кода, где ранжируют проекты (совокупное количество баллов) по общему представлению и соответствию хороших практик. В общем, этот пост - это аккумулированные комментарии/критерии экспертов идеального открытого кода без воды.

Полезно тем, кто:

  • Не знаком с бест практикам.

  • Просто хотел бы узнать какие могут быть критерии таких конкурсов.

  • Кто хочет сделать свой проект более привлекательным.

Общее

Хорошие практики:

  1. Присутствуют соглашения по использованию коммитов (Conventional Commits - все коммиты в едином стиле).

    Сгенерировано с помощью AI, простите 🙏🥺🙏
    Сгенерировано с помощью AI, простите 🙏🥺🙏
  2. Баги с четким описанием (STR).

  3. Есть подробная документация.

  4. Много релизов с детальным описанием.

  5. Если библиотека, то создается для многих платформ.

  6. Каждая feature/fix разрабатывается в своей собственной ветке, с номером выпуска, нет мертвых веток, есть ветки для релизных версий.

  7. Есть Labels для Issues.

  8. Как бонус (окак), есть активные/закрытые доски в разделе Projects в GitHub.

    Сам недавно узнал, что существуют такие доски в GitHub, прикольно.
    Сам недавно узнал, что существуют такие доски в GitHub, прикольно.

Сомнительные практики:

  1. Неактивный проект.

  2. Редкие релизы.

  3. Пропуск релизных версий.

  4. Есть Issues, где люди жалуются, что документация где-то ошибочна.

  5. Релизы не имеют описания либо не полные.

    Пример как можно, хотя тут не адаптировано для пользователей.
    Пример как можно, хотя тут не адаптировано для пользователей.
  6. Проект с одним рабочим пространством; может быть разбит на несколько модулей.

  7. Репозиторий слишком большой. Веб-сайт, core пакет и CLI (+ фронтенд, бэкенд и т.д.) находятся в одном репозитории. Мюсли вслух: "Смотря какого подхода репозиториев вы придерживаетесь: 1) монорепозиторий или 2) на каждый проект свой репозиторий. Разумеется, когнитивно проще воспринимать маленькие репозитории".

  8. Не понятный принцип разделения по пакетам.

  9. Одна ветка для нескольких Issues.

  10. В коде игнорируются ошибки линтера.

  11. Сложно определить, где используется линтер/статический анализатор.

  12. Слишком детальная документация (сайт), текста больше, чем самого кода.

  13. Есть сайт с руководством по использованию приложения, но в руководстве отсутствует навигация, из-за чего пользоваться руководством может быть неудобно.

Код

✅:

  1. Существует комплексная обработка исключений.

  2. Ясные названия переменных.

  3. Методы/функции маленькие, что удобно для их чтения.

❌:

  1. Коммиты прямиком в мастер/мейн ветку.

  2. Ad-hoc нумерация релизов (1.0.0+20250314 или 1.0.0.build452).

  3. Есть stale ветки (ветки, которые давно не обновлялись и потеряли актуальность относительно основной ветки разработки - такие ветки нужно удалять).

  4. Много крупных методов/функций (> 100 линий).

  5. Отсутствие интерфейсов (меньше гибкости в тестировании).

  6. Часто интерфейсы имеют только одну реализацию.

  7. Некоторые объекты имеют излишне малый уровень детализации, что делает код многословным.

  8. Методы/функции имеют слишком большую цикломатическую сложность (большое количество точек принятия решений (ветвления, циклы, операторы if, case, while и т.д.)).

  9. Отсутствуют подробные комментарии к особо важным и сложным разделам библиотеки.

  10. Большое количество параметров в методе.

    Картинка взята из рефакторинг гуру. Как раз там решения такой проблемы.
    Картинка взята из рефакторинг гуру. Как раз там решения такой проблемы.
  11. Присутствуют ненужные комментарии в коде.

  12. Присутствует закомментированный код.

  13. Много лишних пустых строк внутри тела метода.

  14. Странное форматирование: private методы смешаны с public (не сгруппированы вместе).

  15. Различный уровень абстракций на том же package уровне.

  16. Много магических чисел.

  17. Return null, когда этого можно избежать.

  18. Отсутствие шаблонов проектирования в местах, где они могут быть применены (большой условный (case) оператор ⇒ паттерн состояние/стратегия).

  19. В среднем файл содержит 250-500 строк, что слишком много.

  20. Есть узкие места в производительности. Мюсли вслух: "Но помните..."

    Дональд Эрвин Кнут (не забываем как выглядит дядюшка)
    Дональд Эрвин Кнут (не забываем как выглядит дядюшка)

    Преждевременная оптимизация — корень всех зол.

  21. Неиспользуемые импорты в файлах.

  • Windows, JetBrains IDE: Ctrl + Alt + O.

  • Windows, VS Code: Shift + Alt + O.

  • MacOs, JetBrains IDE: ⌃⌥O (Control + Option + O).

  • MacOs, VS Code: ⇧⌥O (Shift + Option + O).

Тесты

✅:

  1. Есть контроль покрытия т��стами >60-80%.

  2. Есть несколько видов тестов: unit, ui + e2e, интеграционные, performance тесты. Мой пример, e2e тестов в Android проекте.

  3. Unit тесты декомпозированы и небольшие.

❌:

  1. С каждым новым релизом падает покрытие тестов (87%>79%>65%>47%).

  2. Тестовые файлы слишком большие (~1000 линий кода).

  3. Тестовые данные подготавливаются непосредственно внутри теста, что делает файл тестирования чрезвычайно эффективным (я, например, в своем последнем проекте для android, подготовил отдельный модуль для таких данных, чтобы шарить между ui и unit тестами, и которые бы не были видны в самом клиентском коде).

  4. Тесты проводятся только на Ubuntu, что затрудняет предоставление каких-либо гарантий для macOS и Windows.

  5. В тестах используются проверки (assertions), которые при падении не дают никакой внятной информации о том, что именно пошло не так.

    Как можно: assertEquals("Expected name:", expectedUser.name, actualUser.name)
    Как можно: assertEquals("Expected name:", expectedUser.name, actualUser.name)
  6. Тесты не проверяют критические сценарии.

  7. Использование if-else внутри тестов.

  8. Трудно понять, что делают некоторые тесты.

  9. Проверка покрытия тестами выполняется при каждом commit`е в каждой ветке. Мюсли вслух: "У меня ещё была проблема с частым редактированием файла Readme.md, что постоянно триггерило CI/CD, в итоге добавил в игнор папку Readme для всех языков".

    Пример из моего кода
    Пример из моего кода

Readme

✅:

  1. Понятная цель проекта в README.md.

  2. Хочется пользоваться проектом после прочтения Readme.

  3. Присутствует локализация (повышает удобство использования для широкого круга пользователей).

  4. Приведены примеры использования библиотеки.

  5. Присутствует доп. документация CHANGELOG, CODE_OF_CONDUCT, LICENSE.

❌:

  1. Нет описания как сбилдить проект.

  2. Скупое README.md, все документы только на сайте, в файле нет быстрой installation/usage.

  3. Битые ссылки в README.md.

  4. Readme есть только на вашем родном языке (не английский).

  5. Беспорядок и большое количество эмодзи в README.md.

    Где-то на просторах интернета. Не Readme, но все же страшный Emoji Hell. P.s. Шакалы пришли - суету навели.
    Где-то на просторах интернета. Не Readme, но все же страшный Emoji Hell. P.s. Шакалы пришли - суету навели.

CI/CD + Pull Requests

✅:

  1. Линтер, как часть CI.

  2. Линтер отрабатывает только на master/main ветке.

  3. Есть CI для релизов.

  4. Есть CI для деплоя/валидации документации.

  5. Есть CI для шаблонов PR/Issues.

    PULL_REQUEST_TEMPLATE.md
    PULL_REQUEST_TEMPLATE.md
  6. Review даже для PR от владельца самого репозитория.

  7. Есть описания к PRs.

  8. Есть ссылки на решаемую проблему (Issues) в PRs.

  9. Release pipeline не задокументирован (через месяц можно забыть, как собирать релиз + контрибьюторы не смогут понять, как работает сборка).

  10. Есть предварительное окружение для PRs.

❌:

  1. Нет CI/CD.

  2. Нет однострочного сценария сборки.

  3. Ручные релизы.

  4. PRs сливаются с failed CI статусами.

  5. Один GitHub workflow.

  6. Большинство PRs - это обновления зависимостей.

  7. Много незакрытых PRs.

  8. Очень большой PR.

  9. CI сломан практически на всех коммитах в мастер.

Contribution

✅:

  1. Детальный раздел для контрибьюторов/отдельный сайт.

  2. Присутствует точный перечень правил (rules) для contribution.

❌:

  1. Нет раздела Call-to-actions для контрибьюторов или CONTRIBUTION.md файла.

  2. Контрибьютору нужно ждать продолжительное время на ответы от мейнтейнера в PR/Issues.

  3. Нет практики Код Ревью - один контрибьютор (сам автор).

  4. Один мейнтейнер, так что нет cross-review (bus factor = 1).

    Картинка взята из статьи на Хабр про Bus-Factor
    Картинка взята из статьи на Хабр про Bus-Factor
  5. Code Review почти не содержат рекомендаций (или токсичные).

Вот и всё, спасибо, что прочитали! Как считаете, что бы вы ещё добавили или может быть что-то кажется вам спорным, буду рад почитать, а по возможности ответить в комментариях.

P.s. Некоторые разделы довольно очевидны, другие буквально “смотря сколько details смотря какой fabric”, надеюсь, все равно было интересно и ваши окуляры не запотели от духоты (как мои)