(java || kotlin) && devOps
368 subscribers
6 photos
1 video
6 files
306 links
Полезное про Java и Kotlin - фреймворки, паттерны, тесты, тонкости JVM. Немного архитектуры. И DevOps, куда без него
Download Telegram
Всем привет!

В продолжение темы функциональности IDEA и подготовки кода к code review, см. https://t.me/javaKotlinDevOps/148
Некоторые проверки и исправления можно подвесить на одно из двух событий:
1) на сохранение файла: Alt-Alt - Actions on Save. Рекомендую включить Reformat code и Optimize import.
2) перед commit на Git сервер - открыть окно Commit (Ctrl-K) и нажать там шестеренку. Рекомендую включить Analyze code, Check TODO и если выполнение тестов занимает приемлемое время - то еще и прогон тестов.
Легко заметить, что набор опций в обоих случаях похож, но на сохранении можно включить только те, где фиксы применяются без участия человека. В частности и Cleanup, и Analyze выполняют правила из набора инспекций (Inspections), только в первом случае включаются только те правила, где есть quick fixes, которые можно применить автоматически.
Насчет Cleanup - IMHO его вполне можно включить на commit, главное перепроверить набор активных правил: Shift-Shift - Inspections, а там включить фильтр Cleanup only. К слову - там еще есть профили с набором правил, можно добавить свой.
И еще важный момент - инспекции из IDEA можно запустить из командной строки, и т.об. включить в CI процесс: https://www.jetbrains.com/help/idea/command-line-code-inspector.html
Они частично повторяют проверки SonarQube, но не идентичны им.

#idea #code_review #clean_code #git
Всем привет!

Уже прошел примерно год как появился ChatGPT. Его активно пытаются применить везде - для решения бизнес-задач, автоматизации рутины и конечно же написания кода. Какую же рутину можно автоматизировать в разработке? А например такую - https://github.com/Nutlope/aicommits

#git #commit
Всем привет!

Микросервисная архитектура, которая становится все более популярной, требует хранения кода каждого сервиса в отдельном репозитории. На всякий пожарный - про остальные требования к микросервисам можно почитать тут https://t.me/javaKotlinDevOps/55
Бонусом мы получаем "штатную" работы IDE, pipeline, механизмов код-ревью. Микросервис подразумевает небольшой объём кода, т.е. все инструменты будут отрабатывать достаточно быстро, с меньшей вероятностью тормозить или падать, меньше вероятность конфликтов merge и т.д.

Зачем же тогда могут понадобится гигантские монорепы?
А ведь примеров хватает:
Яндекс https://habr.com/ru/companies/yandex/articles/469021/
Гугл https://qeunit.com/blog/how-google-does-monorepo/
Microsoft Windows https://habr.com/ru/articles/795635/
И даже Юла: https://habr.com/ru/companies/oleg-bunin/articles/531632/

Отдельно я бы выделил три типовых кейса, не относящиеся к микросервисам:
1) собственно монолит. И причина понятна - странно части монолита собирать из разных репозиториев. Релизный цикл, pipeline все равно же общие
2) игры. Тоже по сути отдельный вид монолита - огромные размеры репо, особенность: основной объем занимают бинарные данные: текстуры, картинки, видео...
3) большие мобильные приложения, SuperApp или стремящиеся к ним. Тоже по сути отдельный случай монолита.

Но в списке выше есть и микросервисы, зачем им лезть в монорепы? Суммируя, можно выделить такие причины:
1) проще контроль над своевременностью обновления библиотек
2) возможность одним PR занести кросс-сервисную фичу. Кстати, полезная штука
3) обучение новичков и обмен знаниями на примерах из других сервисов. Кажется, что это можно сделать и с разными репо, но в монорепе, конечно, удобнее
4) облегчение работы с общим кодом - не надо подключать новые модули явно в каждый сервис, просто работаем с тем, что есть в develop. Опять же все ошибки при выпуске новой версии общего кода ловятся быстрее, т.к. все тесты в одном месте. Конечно тесты, а точнее достаточное тестовое покрытие, должно быть) Рефакторинг, застрагивающий все части системы, как правило связанный с изменением общего API, также проводить проще
5) легче обеспечить унификацию требований к коду. Тоже - можно решить на уровне pipeline и commit hook, но в одном репо проще
6) т.к. модули в монорепо скорее всего работают вместе, а иначе зачем их код хранится вместе - с монорепо можно развернуть тестовый стенд проще, чем с отдельными микросервисами

Что касается минусов - про то как их побороть, можно глянуть статьи выше. Особенно полезна статья про Microsoft, содержащая технические советы по обслуживанию репо на уровне git-а. Часть я знал и ранее, и даже использовал, часть для меня стало сюрпризом. Что особенно важно - все доработки из своего форка git Microsoft портировала в master git. Вот краткий список советов:
1) sparse checkout - выкачивание только нужных папок
2) shallow copy - выкачивание ограниченного числа версии из истории изменений, как правило, только последней
3) клонирование без blob (--filter=blob: none) В blob хранится содержимое файлов. Ясно, что без содержимого файлов разработка невозможна, но в этом режиме git во-первых подкачивает blob для последней версии, а во-вторых - будет подкачивать необходимые ему файлы по требованию
4) также может быть полезно клонирование без checkout, опция --no-checkout, т.е. без копирования собственно файлов в рабочий каталог. Так мы сможем избежать случайного копирования всех файлов до того, как будет проведена фильтрация
5) запуск git maintenance в фоне - обновление графа коммитов, ускоряет выполнение некоторых команд git
6) фоновый монитор файловой системы, настройка git config core.fsmonitor true. Слушает уведомления об изменений файлов в каталоге с исходниками, поэтому git status отрабатывает быстрее.

Более того, в состав Git есть отдельная утилита scalar, из коробки делающая многое из перечисленных выше пунктов.

Итоги: если можно обойтись без монорепо - так и нужно делать. Но если все же решили его использовать - боль можно облегчить)

#git #microservices #monorepo
Всем привет!

Нашел вот такую интересную штуку для работы с git - https://gitbutler.com/ По сути ребята взяли идею IDEA ))) с change list-ами, и сделали из change list полноценную ветку. Ну как полноценную - виртуальную, git про них не знает, вся информация о такой ветке хранится локально. change list-у можно дать название и закоммитить отдельно, а в виртуальной ветке, как и в обычной, кроме того можно делать коммиты, а также объединять, переименовывать и откатывать их. Вот видео с основными фишками https://www.youtube.com/watch?v=PWc4meBj4jo

Цель утилиты - одновременная работа над несколькими ветками. Причем судя по видео создание новых веток и переключение между ними реально быстрое, у меня даже иногда возникала мысль - а не ускорили ли они видео) Ну и надо сказать, утилита пропагандирует минимально возможные изменения в коммите и в ветках, в пределе - одно изменение = один коммит, что также способствует скорости работы. В этом она мне напомнила https://darcs.net/Features, где тоже идет упор на то, что каждая строчка с изменением может стать отдельным коммитом. Но в отличие от Darcs GitButler полностью совместим с Git. И активно развивается.

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

Главное неудобство - нельзя работать с ветками в IDEA, т.к. git client, встроенный в IDEA, ничего не знает о виртуальных ветках.

Второй момент - пока доступно только для Mac и Linux, а так я бы попробовал(

#git
Всем привет!

Я уже рассказывал про 5 возможных моделей ветвления в git https://t.me/javaKotlinDevOps/95
Нашел еще одну, причем уверен некоторым читателям этого блога она покажется знакомым)
Встречайте stacked pull requests.
Вот краткое описание https://www.michaelagreiler.com/stacked-pull-requests
А вот еще более краткое от меня:
1) работаем через Pull Requests (PR), они же Merge Requests
2) PR выстраиваем в лесенку
3) вливаем в обратном порядке
4) при изменениях в родительском PR, например, по результату код-ревью, проталкиваем изменения во все дочерние PR

Основное назначение данной схемы:
1) упор на ревью небольших кусочков кода, разделение фичи на мелкие commit-ы, удобные для ревью
2) разного рода миграции, когда на промежуточных стадиях код не компилируется и тесты не проходят, а все вместе - неудобоваримо для код ревью

Данная модель может работать поверх любого их описанных выше flow, за исключение trunk based. trunk based, напомню, вообще убирает Pull Requests, а процесс ревью осуществляется либо при парном программировании, либо пост-фактум.

Альтернативой является один PR с предположим 10 commits. Но преимущество данной схемы в том, что создавая вместо этого 10 PR автор скорее задумается о том, чтобы каждый из них представлял атомарное изменение, удобное для ревью.

#git #vcs #branching
Всем привет!

Минутка истории. И разных подходов к работе с opensource.

1-я история. Жила была компания Microsoft, и в какой-то момент она "запустила" свою инфраструктуру разработки. Были выделены ресурсы для исправление этой ситуации. Один из примеров такой деятельность - перенос исходников в git, создание своего форка git, проверка его на GitHub и вливание форка в основную ветку git. Вот тут немного подробнее про доработку git под требования Microsoft - большой объем репозитория - https://habr.com/ru/articles/795635/

2-я история. Жила была компания Facebook, тогда еще не иноагент) Компания была молодая, но тоже уже столкнулась с проблемой хранения и организации код-ревью на большом объеме кода. Разработчики компании готовы innersource-ить, чтобы решить проблему. Постучались в git, получили отказ с формулировкой - это частный случай, для основной массы пользователей не нужно, делайте маленькие репозитории. Постучались в Mercurial - там ее pull request согласились принять. Перешли на Mercurial https://habr.com/ru/articles/798881 Но предположу, что часть разработчиков на этом не успокоилась и в результате появился Sapling https://sapling-scm.com/docs/introduction/differences-hg
Это новая Version Control System, которая может работать как со своим форматом repo, так и с git. При этом делает упор на частичное клонирование репо и работу с коммитами: быстрый откат, сохранение истории изменений при слиянии коммитов и даже https://sapling-scm.com/docs/commands/absorb

Тут наверное нужна мораль...)
На первый взгляд подход git более последователен - выбрали лидера рынка, допилили, вернули в основную ветку, помогли opensource сообществу. Но с другой стороны git хоть и является стандартом, но не идеален. И Sapling решает ряд его проблем. Кто-то должен протаптывать новые тропы, пусть и ценой чуть большего беспорядка в своей инфраструктуре разработки

#git #vcs
Всем привет!

Небольшой пост из серии "хозяйке на заметку")

Можно ли слить в git 2 проекта, не имеющих общей истории?
Первый вопрос, который тут возникает - а зачем???
Но похоже иногда такая потребность есть, потому что у git merge есть опция --allow-unrelated-histories.
Можно предположить, что такая опция может понадобится если проект начал разрабатываться 2 людьми, при этом забыли сделать общий первый commit. Или были жесткие rewrite-ы)

#git #tricks
Примерный набор команд:
git config submodule.recurse true # добавляет ключ --recurse-submodules ко всем командам кроме clone. В частности checkout и pull
git config diff.submodule log # отображать также изменения в подмодулях при выполнении diff в корне
git config alias.clones 'clone --recurse-submodules' # подтягивать подмодули при клонировании
git config alias.diffs '!'"git diff && git submodule foreach 'git diff'" # показать изменения по всем подмодулям
git config alias.pushs 'push --recurse-submodules=on-demand' # запушить изменения вначале в подмодулях, потом в основной проект
git config alias.updates 'submodule update --remote --merge' # подтянуть изменения подмодулей из удаленных репозиториев и влить их в локальную копию. После этого можно самому вносить изменения в подмодуль

В любом случае предлагаю прочитать статью по ссылке выше.

#git #api #integraion
Вроде простая картинка про работу git, но думаю будет полезно. Ключевые моменты - наличие локального репозитория и staging area #git
Всем привет!

Уже писал про импортозамещение в ПО:

1) IDE https://t.me/javaKotlinDevOps/353
2) Spring plugins https://t.me/javaKotlinDevOps/358

Две ремарки - термин импортозамещение сильно скомпрометировали, но другой более удачный я пока не придумал) И некоторые из описываемых продуктов разрабатывались не для импортозамещения, но события последних лет дали неплохой импульс для их развития.

Так вот, на Highload-е нашёл 2 аналога GitLab/GitHub:

1) GitVerse от Сбера. Как и GigaIDE находится в процессе разработки, в частности аналог Git Actions планируют допилить в ближайших релизах, сейчас для настройки требуется много ручных действий. Две основные фишки: интеграция с GigaCode и облачная IDE на основе VS Code, доступная в рамках бета-тестирования. Для облачной IDE нужен аккаунт и настройка в облаке Сбера - cloud.ru. И к сожалению не поддерживается Java - зато есть Python, Go, С#. Интерфейс аскетичный, но подсветка синтаксиса, AutoComplete, работа с тестами, отладка и консоль есть. Пока все бесплатно, конечно временно) Еще фишка - доступно AI ревью кода https://gitverse.ru/docs/collaborative-work/code-review/#ai-ревью И в целом ревью неплохое - я скормил ему кусок кода "с запахами", и AI нашел там 6 багов из 18. Минус: все работает медленно - думаю сказывается бесплатность и статус беты.

2) GitFlic от Астра (которая Linux). В нём есть Ci/CD, реестр артефактов, статический анализ кода (названный почему-то SAST), REST API и интеграция с Telegram и JIRA. И платная версия, позволяющая добавлять более 5 человек в private репозиторий плюс расширенную поддержку https://gitflic.ru/price Пока нет полноценно баг-трекера, обещают сделать. Еще плюс - тут я быстро нашел как разрешить force push, в отличие от GitVerse)

GitFlic на данный момент выглядит законченным продуктом, но у GitVerse есть свои плюсы - см. выше. Плюс тесная интеграция с облачным провайдером cloud.ru

#импортозамещение #git
(Не) храните большие бинарные файлы в git

Есть такое общеизвестное правило - никогда не храните большие бинарные файлы в git. Почему?
Причин несколько:

1) большие файлы как правило бинарные, а при работе с бинарными файлами мы теряем значительную часто возможностей git - просмотр diff-ов, да процесс code review в целом

2) git начинает тормозить при разрастании репозитория, а учитывая, что хранится вся история изменений - с большими файлами выйти на этот предел (десятки и сотни Gb, вот тут есть пример от Microsoft https://t.me/javaKotlinDevOps/272) уже значительно проще.

И если с первой причиной что-то сделать сложно, то для второй решение есть. И называется оно Git LFS https://git-lfs.com/

Для начала небольшая справка. При git clone скачивается следующая информация:

1) метаданные
а) настройки git
б) список существующих веток и тэгов

2) история коммитов по всем веткам (.git)

3) актуальные версии файлов в текущей ветке

Суть решения:

1) большие файлы хранятся отдельно от текстовых, с текстовыми файлами хранятся только ссылки на них. Переиспользуем возможности файловой системы Linux

2) при клонировании репозитория большие файлы копируются только для текущей ветки, что ускоряет загрузку

Главный вопрос - когда это все может понадобится? Видится такой вариант - хранить контент вместе с исходниками. Вообще контент лучше хранить в CMS, но, например, если есть тесная связь контента с релизом, то может иметь смысл хранить их рядом. Что точно не стоит хранить в git - так это jar-ники.

Еще важный момент - для того, что Git LFS заработал, нужно:
1) проинсталлировать его на сервере
2) включить на репозитории
3) добавить в репозиторий по маске список файлов, которые надо считать большими.
4) существующие файлы в LFS не попадают, их нужно добавить заново или мигрировать

В целом LFS работает прозрачно, но команды git lfs clone и git lfs pull оптимизированы для работы с LFS и загружают данные быстрее.

Проект open source и поддерживаемый, был создан усилиями заинтересованных лиц - GitHub, Bitbucket.

#git