Чему я научился за два года работы над Open Source проектом
от aNNiMON
1 января 2015 года я создал репозиторий на GitHub, не подозревая, что он вскоре обретёт популярность. В этой статье я опишу, через что мне пришлось пройти, чему я за это время научился и дам советы по улучшению своего проекта.
О проекте
Мой проект — библиотека Lightweight Stream API, которая приносит функционал Java 8 Stream API в ранние версии Java, в том числе и для Android. Java 8 в тот момент наращивала популярность, Stream API был отличным решением для манипуляции данными, да и проект Retrolambda уже позволял использовать языковые возможности Java 8 в ранних версиях Java.
Опыта работы со Stream API хватало, знаний для его реализации на старых версиях Java — тоже, вот я и решил делать бэкпорт.
Совет №1
В мире существует огромное множество библиотек, но это не значит, что все идеи уже реализованы. Может быть вы придумаете что-то новое, может быть вы сможете сделать то, что уже есть, но более удобнее/функциональнее/оптимальнее. Даже что-то, что сократит рутинные действия на два шага, уже может помочь людям. Не бойтесь писать свои велосипеды, но умейте трезво оценить насколько этот велосипед будет полезным.
Первые шаги
Первый релиз состоялся через четыре дня после создания репозитория. На тот момент там были исходники библиотеки, исходники тестов, файлы проекта для NetBeans, а также README с кратким описанием проекта и его возможностей. Всё это заняло 27 коммитов.
Совет №2
Всегда для своих проектов используйте системы контроля версий. Это поможет в дальнейшем вернуться на любую точку в истории проекта и посмотреть, что там было. Это не значит, что нужно выкладывать проекты на GitHub или куда-то ещё, нет. Речь именно о локальной истории.Совет №3
Обязательно создавайте README. Не всегда название проекта говорит само за себя, не всякий полезет смотреть исходники, чтобы узнать больше о проекте. Без описания проекта, многие просто пройдут мимо.
Спустя неделю с момента создания проекта, библиотекой уже можно было пользоваться, поэтому я создал другой репозиторий с примером использования на Android. А также написал статью, с пояснением и примерами.
Совет №4
Примеры и описание — дополнительный плюс вашему проекту.
На этом моё дело считалось завершенным, так я думал на тот момент. Основные функции библиотека выполняла, работала пусть не оптимально, но зато была компактной. Разработка была отложена в долгий ящик.
Изредка на мой репозиторий кто-то натыкался, ставил звёздочки. Примерно к апрелю там собралось около 20 звёзд, что для меня было уже много.
В конце апреля был открыт первый issue, меня попросили опубликовать библиотеку в Maven или jCenter. Пришлось разбираться, как это сделать и уже через два дня issue был закрыт, а библиотека com.annimon:stream появилась в Maven Central. Помню, сидеть пришлось до 3 часов ночи, но зато научился публиковать библиотеки и теперь у меня есть свой репозиторий в Maven. Спасибо тому, кто открыл тот issue.
Совет №5
Блуждая по репозиториям, не бойтесь открывать issue и просить разработчиков что-либо сделать. Это будет хорошим вкладом не только в проект, но и, возможно, поможет самому разработчику узнать что-то новое.
Примерно в то же время меня спросили, под какой лицензией распространяется библиотека и тогда я понял, что для зарубежных разработчиков это немаловажный вопрос.
Совет №6
При создании репозитория, указывайте, под какой лицензией вы хотите распространять свой проект. Отнеситесь к этому вопросу серьёзно — в одном из проектов под WTFPL люди жаловались, что разработчику следовало бы выбрать что-то более нормальное, ведь WTFPL будто говорит, что человеку наплевать на свой проект. Вместо WTFPL отлично подойдёт MIT.
Набираем обороты
В начале июля кто-то из зарубежных разработчиков опубликовал статью про использование Java 8 на Android. В статье говорилось про Retrolambda и про мою библиотеку. Я хорошо помню тот вечер, мне нужно было уезжать, все вещи были собраны, до отъезда 40 минут. Я захожу на GitHub с мобильного клиента, а там в ленте полторы страницы уведомлений о том, что кто-то поставил звёздочку моему проекту. В тот вечер репозиторий попал в GitHub Trending Repos, но я этого так и не увидел.
Появление этой статьи стало переломным моментом. Даже сейчас, спустя полтора года, как минимум 25 человек каждую неделю попадают на страницу моего репозитория.
Много радоваться не пришлось, совсем скоро появились пул реквесты, которые нужно было принимать, и новые issue, которые нужно было решать. Появился человек, который добавил немного функционала, вслед за ним ещё один. Тут-то я по-настоящему ощутил всю прелесть Open Source разработки.
Совет №7
Создайте в своём репозитории хорошую атмосферу. Вам не составит труда поблагодарить людей за найденный баг и уж тем более за внесённые изменения.Совет №8
Старайтесь как можно быстрее реагировать на вопросы и предложения. Если бы вы сделали изменение в проекте, вам вряд ли захотелось бы ждать неделю, а то и больше, пока разработчики примут её на рассмотрение, это быстро бы отбило желание помогать проекту.
С ростом популярности, проекту приходилось соответствовать своему статусу. Просто исходников было уже мало: людям, использующим библиотеку, нужна была документация, одними файлами проекта NetBeans тоже было не обойтись.
Совет №9
Каким бы крутым ни был ваш проект, без документации в нём будет сложно разобраться.Совет №10
Используйте популярную систему сборки, а лучше несколько, иначе круг людей, способных собрать ваш проект и уж тем более сделать pull request будет очень мал.
Если вы спросите меня, что я больше всего ненавижу делать, я отвечу — писать документацию. Писать JavaDocs на английском, внимательно расставлять параметры, формулировать лаконичные описания методов, это очень рутинная задача, требующая в свою очередь большой концентрации. На заполнение джавадоков к 70 методам у меня ушло двое суток. Но это была необходимая жертва. Надеюсь, кому-то это впоследствии помогло.
А вот с системой управления сборкой было всё куда интересней. На замену Ant-проекту пришел Gradle и открылась возможность подключения Continuous Integration.
Continuous Integration
Непрерывная интеграция (CI) + Open Source проект = огромное упрощение процесса разработки. После того, как я подключил одну из таких систем, управлять проектом стало проще.
Достоинства:
- очень легко подключить;
- бесплатно для проектов с открытыми исходниками;
- сборка выполняется без вашего участия на мощных серверах сервисов CI;
- помогает быстро узнать состояние проекта или отдельного пул реквеста;
- способно автоматически выполнить какие-либо действия (сборка бинарников, генерирование документации и многое другое);
- возможность сборки на различных конфигурациях.
Совет №11
Используйте системы непрерывной интеграции. Это существенно упрощает разработку.
Что конкретно ощутил я?
1. На моём ПК установлена только JDK8, собирал я для target 1.6. Благодаря CI, я получил возможность сборки на openjdk7, openjdk8, oraclejdk7 и oraclejdk8. Несколько раз это помогло выявить ошибки: однажды я воспользовался классом, который есть только в 1.8, компиляция на моём ПК прошла успешна, но вот на openjdk7 и oraclejdk7 сборка не прошла. Без CI, вероятно, ошибка закралась бы в релиз. И ещё пару раз CI помогла найти ошибки в тестах, например реализация Set у openjdk и oraclejdk несколько отличается, так что пришлось переписать пару методов. Без CI я бы этого так и не узнал.
2. Людям легче вносить изменения, мне легче видеть, что в этих изменениях сделано. Благодаря тесной связи CI с GitHub, человек, создавший пул реквест, видит, что его изменения успешно прошли сборку и тестирование (или наоборот, не прошли). Мне же видно, что в пул реквесте было сделано. Если там не хватает тестов, я сразу же могу попросить человека сделать их. Если не была пройдена какая-то проверка, я могу подсказать, что необходимо сделать для решения проблемы.
Совет №12
Используйте различные конфигурации для сборки. Это позволит вовремя выявить ошибки.
Следующим приятным моментом, который подарил CI, было подключение метрики покрытия тестами. С самого начала проекта я уделял много времени написанию тестов, так что покрытие было достаточно высоким. Добив показатель до 100% и повесив в README бейдж с метрикой, я одновременно упростил поддержку проекта и показал, что библиотека хорошо протестирована.
Совет №13
Уделяйте внимание тестированию. Может показаться, что это трата времени — за время написания тестов для одного метода, уже можно было бы написать несколько других. Но нет, потраченное время окупится. В дальнейшем, внеся ошибочное изменение, вы увидите ошибку сразу же, а не спустя пару недель от какого-нибудь разозлённого клиента. К тому же покрытый тестами код добавляет уверенности: можно делать любые изменения, рефакторить, не боясь, что в проекте что-то сломается. Без тестов, скажу честно, я бы лишний раз не стал ничего менять в проекте, а значит было бы меньше оптимизаций или, как минимум, плохой код.
Совет №14
Подключите к CI систему замеров метрик (покрытие тестами, статический анализ кода, контроль качества и т.п.). Это позволит контролировать процесс разработки, например, создав pull request, разработчик сможет увидеть, что он забыл написать тест или где-то применил неоптимальную конструкцию.
Кстати, с замерами уровня покрытия тестами был один интересный момент. В погоне за желаемым показателем 100% добавился азарт и энтузиазм в написании кода. Думаю, у тех, кто вносил изменения в проект, этот азарт тоже присутствовал. Во всяком случае, не помню ни одного пул реквеста, который уменьшил бы покрытие тестами. Все старались добить показатель до 100%.
Итоги
За два года разработки проекта я узнал больше нового и, главное, полезного, чем за столько же лет учёбы. В проект приходили интересные люди, которые не только улучшали проект, но и открывали мне что-то новое.
До проекта я не знал как правильно писать тесты, не заботился о документации, не знал о Continuous Integration, инструментах замера покрытия кода, JaCoCo, Cobertura, Hamcrest, Mockito, не знал о том, что простые смертные могут добавлять свои библиотеки в Maven Central и JCenter.
Тот момент, когда я думал, что библиотека готова, был лишь начальной стадией его развития. С тех пор мне пришлось добавить кучу всего, поставить на первый план не легковесность, а производительность. Иными словами, изменить своё видение проекта. За два года было написано много кода, потрачено много времени.
Взамен я получил море удовольствия, познакомился с интересными людьми и полезными технологиями. Ну и, конечно же, немного упростил жизнь тем людям, кто пользуется моей библиотекой.
Совет №15
Упрощайте жизнь другим людям. Любыми способами.
И вот что мы имеем сейчас.
График просмотров репозитория
Количество загрузок библиотеки с JCenter в 2016 году
Загрузки библиотеки с JCenter в 2016 году по странам
Краткий список советов, освещённых далее
О проекте
Мой проект — библиотека Lightweight Stream API, которая приносит функционал Java 8 Stream API в ранние версии Java, в том числе и для Android. Java 8 в тот момент наращивала популярность, Stream API был отличным решением для манипуляции данными, да и проект Retrolambda уже позволял использовать языковые возможности Java 8 в ранних версиях Java.
Опыта работы со Stream API хватало, знаний для его реализации на старых версиях Java — тоже, вот я и решил делать бэкпорт.
Совет №1
В мире существует огромное множество библиотек, но это не значит, что все идеи уже реализованы. Может быть вы придумаете что-то новое, может быть вы сможете сделать то, что уже есть, но более удобнее/функциональнее/оптимальнее. Даже что-то, что сократит рутинные действия на два шага, уже может помочь людям. Не бойтесь писать свои велосипеды, но умейте трезво оценить насколько этот велосипед будет полезным.
Первые шаги
Первый релиз состоялся через четыре дня после создания репозитория. На тот момент там были исходники библиотеки, исходники тестов, файлы проекта для NetBeans, а также README с кратким описанием проекта и его возможностей. Всё это заняло 27 коммитов.
Совет №2
Всегда для своих проектов используйте системы контроля версий. Это поможет в дальнейшем вернуться на любую точку в истории проекта и посмотреть, что там было. Это не значит, что нужно выкладывать проекты на GitHub или куда-то ещё, нет. Речь именно о локальной истории.Совет №3
Обязательно создавайте README. Не всегда название проекта говорит само за себя, не всякий полезет смотреть исходники, чтобы узнать больше о проекте. Без описания проекта, многие просто пройдут мимо.
Спустя неделю с момента создания проекта, библиотекой уже можно было пользоваться, поэтому я создал другой репозиторий с примером использования на Android. А также написал статью, с пояснением и примерами.
Совет №4
Примеры и описание — дополнительный плюс вашему проекту.
На этом моё дело считалось завершенным, так я думал на тот момент. Основные функции библиотека выполняла, работала пусть не оптимально, но зато была компактной. Разработка была отложена в долгий ящик.
Изредка на мой репозиторий кто-то натыкался, ставил звёздочки. Примерно к апрелю там собралось около 20 звёзд, что для меня было уже много.
В конце апреля был открыт первый issue, меня попросили опубликовать библиотеку в Maven или jCenter. Пришлось разбираться, как это сделать и уже через два дня issue был закрыт, а библиотека com.annimon:stream появилась в Maven Central. Помню, сидеть пришлось до 3 часов ночи, но зато научился публиковать библиотеки и теперь у меня есть свой репозиторий в Maven. Спасибо тому, кто открыл тот issue.
Совет №5
Блуждая по репозиториям, не бойтесь открывать issue и просить разработчиков что-либо сделать. Это будет хорошим вкладом не только в проект, но и, возможно, поможет самому разработчику узнать что-то новое.
Примерно в то же время меня спросили, под какой лицензией распространяется библиотека и тогда я понял, что для зарубежных разработчиков это немаловажный вопрос.
Совет №6
При создании репозитория, указывайте, под какой лицензией вы хотите распространять свой проект. Отнеситесь к этому вопросу серьёзно — в одном из проектов под WTFPL люди жаловались, что разработчику следовало бы выбрать что-то более нормальное, ведь WTFPL будто говорит, что человеку наплевать на свой проект. Вместо WTFPL отлично подойдёт MIT.
Набираем обороты
В начале июля кто-то из зарубежных разработчиков опубликовал статью про использование Java 8 на Android. В статье говорилось про Retrolambda и про мою библиотеку. Я хорошо помню тот вечер, мне нужно было уезжать, все вещи были собраны, до отъезда 40 минут. Я захожу на GitHub с мобильного клиента, а там в ленте полторы страницы уведомлений о том, что кто-то поставил звёздочку моему проекту. В тот вечер репозиторий попал в GitHub Trending Repos, но я этого так и не увидел.
Появление этой статьи стало переломным моментом. Даже сейчас, спустя полтора года, как минимум 25 человек каждую неделю попадают на страницу моего репозитория.
Много радоваться не пришлось, совсем скоро появились пул реквесты, которые нужно было принимать, и новые issue, которые нужно было решать. Появился человек, который добавил немного функционала, вслед за ним ещё один. Тут-то я по-настоящему ощутил всю прелесть Open Source разработки.
Совет №7
Создайте в своём репозитории хорошую атмосферу. Вам не составит труда поблагодарить людей за найденный баг и уж тем более за внесённые изменения.Совет №8
Старайтесь как можно быстрее реагировать на вопросы и предложения. Если бы вы сделали изменение в проекте, вам вряд ли захотелось бы ждать неделю, а то и больше, пока разработчики примут её на рассмотрение, это быстро бы отбило желание помогать проекту.
С ростом популярности, проекту приходилось соответствовать своему статусу. Просто исходников было уже мало: людям, использующим библиотеку, нужна была документация, одними файлами проекта NetBeans тоже было не обойтись.
Совет №9
Каким бы крутым ни был ваш проект, без документации в нём будет сложно разобраться.Совет №10
Используйте популярную систему сборки, а лучше несколько, иначе круг людей, способных собрать ваш проект и уж тем более сделать pull request будет очень мал.
Если вы спросите меня, что я больше всего ненавижу делать, я отвечу — писать документацию. Писать JavaDocs на английском, внимательно расставлять параметры, формулировать лаконичные описания методов, это очень рутинная задача, требующая в свою очередь большой концентрации. На заполнение джавадоков к 70 методам у меня ушло двое суток. Но это была необходимая жертва. Надеюсь, кому-то это впоследствии помогло.
А вот с системой управления сборкой было всё куда интересней. На замену Ant-проекту пришел Gradle и открылась возможность подключения Continuous Integration.
Continuous Integration
Непрерывная интеграция (CI) + Open Source проект = огромное упрощение процесса разработки. После того, как я подключил одну из таких систем, управлять проектом стало проще.
Достоинства:
- очень легко подключить;
- бесплатно для проектов с открытыми исходниками;
- сборка выполняется без вашего участия на мощных серверах сервисов CI;
- помогает быстро узнать состояние проекта или отдельного пул реквеста;
- способно автоматически выполнить какие-либо действия (сборка бинарников, генерирование документации и многое другое);
- возможность сборки на различных конфигурациях.
Совет №11
Используйте системы непрерывной интеграции. Это существенно упрощает разработку.
Что конкретно ощутил я?
1. На моём ПК установлена только JDK8, собирал я для target 1.6. Благодаря CI, я получил возможность сборки на openjdk7, openjdk8, oraclejdk7 и oraclejdk8. Несколько раз это помогло выявить ошибки: однажды я воспользовался классом, который есть только в 1.8, компиляция на моём ПК прошла успешна, но вот на openjdk7 и oraclejdk7 сборка не прошла. Без CI, вероятно, ошибка закралась бы в релиз. И ещё пару раз CI помогла найти ошибки в тестах, например реализация Set у openjdk и oraclejdk несколько отличается, так что пришлось переписать пару методов. Без CI я бы этого так и не узнал.
2. Людям легче вносить изменения, мне легче видеть, что в этих изменениях сделано. Благодаря тесной связи CI с GitHub, человек, создавший пул реквест, видит, что его изменения успешно прошли сборку и тестирование (или наоборот, не прошли). Мне же видно, что в пул реквесте было сделано. Если там не хватает тестов, я сразу же могу попросить человека сделать их. Если не была пройдена какая-то проверка, я могу подсказать, что необходимо сделать для решения проблемы.
Совет №12
Используйте различные конфигурации для сборки. Это позволит вовремя выявить ошибки.
Следующим приятным моментом, который подарил CI, было подключение метрики покрытия тестами. С самого начала проекта я уделял много времени написанию тестов, так что покрытие было достаточно высоким. Добив показатель до 100% и повесив в README бейдж с метрикой, я одновременно упростил поддержку проекта и показал, что библиотека хорошо протестирована.
Совет №13
Уделяйте внимание тестированию. Может показаться, что это трата времени — за время написания тестов для одного метода, уже можно было бы написать несколько других. Но нет, потраченное время окупится. В дальнейшем, внеся ошибочное изменение, вы увидите ошибку сразу же, а не спустя пару недель от какого-нибудь разозлённого клиента. К тому же покрытый тестами код добавляет уверенности: можно делать любые изменения, рефакторить, не боясь, что в проекте что-то сломается. Без тестов, скажу честно, я бы лишний раз не стал ничего менять в проекте, а значит было бы меньше оптимизаций или, как минимум, плохой код.
Совет №14
Подключите к CI систему замеров метрик (покрытие тестами, статический анализ кода, контроль качества и т.п.). Это позволит контролировать процесс разработки, например, создав pull request, разработчик сможет увидеть, что он забыл написать тест или где-то применил неоптимальную конструкцию.
Кстати, с замерами уровня покрытия тестами был один интересный момент. В погоне за желаемым показателем 100% добавился азарт и энтузиазм в написании кода. Думаю, у тех, кто вносил изменения в проект, этот азарт тоже присутствовал. Во всяком случае, не помню ни одного пул реквеста, который уменьшил бы покрытие тестами. Все старались добить показатель до 100%.
Итоги
За два года разработки проекта я узнал больше нового и, главное, полезного, чем за столько же лет учёбы. В проект приходили интересные люди, которые не только улучшали проект, но и открывали мне что-то новое.
До проекта я не знал как правильно писать тесты, не заботился о документации, не знал о Continuous Integration, инструментах замера покрытия кода, JaCoCo, Cobertura, Hamcrest, Mockito, не знал о том, что простые смертные могут добавлять свои библиотеки в Maven Central и JCenter.
Тот момент, когда я думал, что библиотека готова, был лишь начальной стадией его развития. С тех пор мне пришлось добавить кучу всего, поставить на первый план не легковесность, а производительность. Иными словами, изменить своё видение проекта. За два года было написано много кода, потрачено много времени.
Взамен я получил море удовольствия, познакомился с интересными людьми и полезными технологиями. Ну и, конечно же, немного упростил жизнь тем людям, кто пользуется моей библиотекой.
Совет №15
Упрощайте жизнь другим людям. Любыми способами.
И вот что мы имеем сейчас.
График просмотров репозитория
Количество загрузок библиотеки с JCenter в 2016 году
Загрузки библиотеки с JCenter в 2016 году по странам