В свободное и не свободное время[1] я развиваю несколько своих проектов на github, а также, по мере сил, участвую в жизни интересных для меня, как программиста, проектах.
Недавно один из коллег попросил консультацию: как выложить разработанную им библиотеку на github. Библиотека никак не связана с бизнес-логикой приложения компании, по сути это адаптер к некоему API, реализующему определённый стандарт. Помогая ему, я понял что вещи, интуитивно понятные и давно очевидные для меня, в этой области, совершенно неизвестны человеку делающему это впервые и далёкому от Open Source.
Я провел небольшое исследование и обнаружил что большинство публикаций по этой теме на habrahabr освещают тему участия (contributing), либо просто мотивируют каким-нибудь образом примкнуть к Open Source, но не дают исчерпывающей инструкции как правильно оформить свой проект. В целом в рунете, если верить Яндекс, тема освещена со стороны мотивации, этикета контрибуции и основ пользования github. Но не с точки зрения конкретных шагов, которые следует предпринять.
Так что из себя представляет стильный модный молодёжный Open Source проект в 201* году?
Данная статья не решает следующие задачи:
- мотивация к участию в Open Source
- PR и продвижение для своих OS-проектов
- обсуждение нюансов программирования
- основы пользования git / github
Для тех кто знает, и является мейнтейнером своего Open Source проекта, или активным контрибьютором в чужих, большинство рассматриваемых в этой статье моментов может быть хорошо знакомым, либо интуитивно понятным. Но, ничто не стоит на месте, и порой я замечаю новые для себя нюансы, которые ещё не использовал, и которые бы повысили удобство пользователей. Поэтому в комментариях буду рад увидеть ваши интересные идеи, дополняющие статью.
Must Have
Сперва хотелось бы рассмотреть "must have" для любого OS-проекта. Минимальный джентльменский набор, без которого ваш проект не будет производить впечатление законченного. Лично я, при выборе библиотеки, считаю каждый из этих пунктов обязательным, для того чтобы добавить новую зависимость в менеджере пакетов.
Github
Очевидно что github лидирует как
В каждом репозитории должен быть .gitignore
, соответствующий языку и типу проекта. Выбрать шаблон для вашего случая можно здесь.
Общее правило: код — который генерируется в процессе разработки, тестирования, сборки/компиляции, рантайма — должен находиться в gitignore.
Лицензия
Второй маленький шаг для проекта и огромный для человечества — выбор и создание файла лицензии.
Github, при создании проекта, позволяет выбрать подходящую лицензию. Файл должен называться LICENSE
, без расширения.
Очень подробная статья на тему выбора свободной лицензии от marked-one
README.md
Этот файл является лицом вашего проекта. Именно его видит пользователь заходя на главную страницу. Содержимое этого же файла будет показано в большинстве сервисов с которыми вы интегрируетесь (например реестры пакетных менеджеров и т.п.).
Как минимум он должен содержать общее описание по следующим пунктам:
- Назначение библиотеки (проекта, инструмента, фреймворка)
- Системные требования (версия языка, требования к ресурсам, системные зависимости, нужные расширения)
- Шаги по установке, сборке, запуску
- Примеры использования или ссылки на документацию
Версионирование (SemVer) и журнал изменений (CHANGELOG.md)
После публикации кода, вы несёте моральную ответственность перед вашими пользователями за его работоспособность в случае обновлений. Для этого умными людьми были придуманы две отличные штуки. Приведу лишь ссылки, разобраться в них нетрудно, надо лишь прочитать:
Всегда следуйте им, и ваша карма будет безукоризненной.
Тестирование
Если вы ещё не инфицированы TDD, то могу заразить =)
Чем можно доказать, что код вообще работает, если не тестами? Как доказать, что 100% вашего кода работает ожидаемым образом, как не полным покрытием?
Конечно 100% покрытие не даёт 100% гарантии отсутствия багов и верности реализации, но как ничто другое приближает к этому недостижимому идеалу.
Тесты — единственный формальный способ доказать корректность и работоспособность кода потенциальному пользователю-программисту. Обещания оставьте гуманитариям, коллегам из QA и девушкам.
CI
Travic-ci подключается к github в пару кликов. Наличие .travic.yml
в репозитории — обязательно, если, конечно, вы не используете что-то более сложное.
Пакетный менеджер
Если для вашей платформы есть пакетный менеджер, потрудитесь чтобы ваш код мог быть получен через него. Composer, npm, maven, etc.
Также важно чтобы актуальная версия (в соответствии с SemVer, ага) автоматически, после прохождения CI (и тестирования, ага), попадала в реестр.
К счастью, для большинства мейнстримовых языков такие менеджеры есть и интегрируются с github / travis в пару кликов / строчек конфига.
Зависимости вашего кода, само собой должны быть надлежащим образом оформлены при помощи файла конфигурации того же менеджера.
Внедрение зависимостей, SOLID, etc
Постарайтесь также взглянуть на свой код со стороны.
Если это библиотека общего назначения или фреймворк: насколько удобно будет его использовать в проекте построенном на совершенно другом фреймворке или без оного? Как насчёт Open/Closed? Можно ли заинжектить по интерфейсу один из компонентов вашей библиотеки, который кому-то потребовалось поменять? Все ли опции поддаются простому программному конфигурированию?
Если это утилита, например командной строки: хорошо ли она подходит для встраивания в имеющиеся скрипты автоматизации? Как насчёт полезных сообщений об ошибках и корректных кодах возврата?
Наиболее жизнеспособные и удачные проекты — это те, которые были рождены в муках, в реальных боевых условиях и извлечены из недр копи-пасты на белый свет.
Не примерив на себя роль пользователя, вы не сможете адекватно спроектировать интерфейс приложения.
Стандарты
Используйте стандарты языка и его сообщества: JSR, PSR, общепринятые code styles. Если вы до этого не вникали в эти дебри, самое время!
Посмотрите на мейнстримовые библиотеки для сходных задач в вашем языке: какие интерфейсы и стандарты реализуют они?
Речь не только про конкретные RFC, но и в целом это касается стандартных подходов к решению типичных задач.
Не критично, но очень желательно
Подробная документация, примеры, FAQ
Минимальные примеры использования вашего кода должны быть в README. Но, надеюсь, вы, как программист, согласитесь насколько приятно быстро находить ответы на свои вопросы.
Есть несколько способов организовать проактивную помощь вашим пользователям. Каждый из них по своему удобен и эффективен в зависимости от специфики проекта и аудитории.
- Wiki-документация. Может быть размещена на том же github, либо в виде набора md файлов в самом репозитории или на github pages, или вообще на отдельном сайте.
- Небольшие проекты-репозитории с типичными примерами использования. Бывает очень полезно для проектов, представляющих собой что-то среднее между фреймворком и библиотекой.
- FAQ — пополняемый из собственного и пользовательского опыта.
Для реактивной поддержки github имеет issues.
Файлы CONTRIBUTING.md, CONTRIBUTORS.md, ISSUE_TEMPLATE.md, PULL_REQUEST_TEMPLATE.md
Если вам повезло, и вы не единственный разработчик, либо настолько амбициозны, что рассчитываете на дикий прилив свежих сил сразу после публикации на github, то этот набор вам поможет.
В первом случае: работать по одним правилам и не холиварить по пустякам.
Во втором: облегчить участие новичков и исключить недопонимание.
Сюда же стоит отнести использование линтеров, статических анализаторов, автоформаттеров и прочего — все это очень облегчает командную разработку.
В настройка github вы можете найти чеклист, который сориентирует вас чего не хватает проекту для полного лоска.
Шик, блеск, красота
И, напоследок, опциональные фишки, которые, тем не менее, производят приятное впечатление и могут существенно помочь пользователям вашего кода.
Бейджи
Отличная штука. Очень удобно с первого взгляда на README получить представление о статусе проекта. Лично я считаю наиболее наглядными следующие характеристики:
- процент покрытия
- актуальная стабильная версия
- статистика скачиваний в реестре / звезд, или другая фаллометрия свидетельствующая о популярности или востребованности
Главное не переусердствовать.
Интеграция с сервисами
Рынок CI последние годы очень активно развивался и существует огромный выбор сервисов по анализу кода, хранению артефатов сборки и тестирования и т.п. Большинство из них, как правило, легко интегрируются с github и бесплатны для открытых проектов.
- https://codecov.io
- https://codeclimate.com/
- https://www.bithound.io
- https://scrutinizer-ci.com/
- … тысячи их под любой язык и задачу
Делитесь в комментария интересными находками!
Docker?
Казалось бы, при чём тут докер?
А вот: он может быть использован для тестирования, разработки и поставки вашего детища.
Некоторые CI-сервисы используют докер. Некоторые виды тестирования удобно автоматизировать при помощи контейнеризации.
Раньше приходилось использовать vagrant для унификации рабочего окружения. Docker вполне может взять эту задачу на себя. Многие задачи по сборке, которые надо выполнять на машине разработчика могут быть контейнеризированы. Это поможет избежать дополнительных усилий по настройке локальной машины под проект и проблем типа "а у меня все работает...".
Некоторые программные решения удобно поставлять в виде докер-образа, учитывая что многие уже используют docker-compose и stack в своих проектах. В этом случае подключение вашей разработки упрощается до пары строчек в docker-compose.yml.
[1]: я считаю что в рамках работы почти всегда есть место Open Source. Например: на предыдущей работе я использовал одну собственную библиотеку в продакшен, а другой сервис, разработанный на выходных для текущих нужд проекта, также по договорённости с техдиром, оставил на github и docker hub. Если библиотека не связана с бизнес-логикой проекта, и вы готовы уделить ей пару часов на досуге, то адекватное начальство всегда пойдёт вам навстречу. Ведь это взаимовыгодный шаг: компания получает бонусные человекочасы (сейчас, и потенциально даже после вашего ухода), вы — публичное портфолио за рамками NDA.
Автор: samizdam