Читать в телеге. Когда-то там были посты не только от меня.
Неполное клонирование
Во всяких CI и/или тестовых окружениях обычно не нужна вся история коммитов, а достаточно выгрузить состояние репозитория на момент определенного (чаще всего последнего) коммита. Чтобы сэкономить время и снизить вероятность ошибки сети, если она нестабильна, можно вместо тупого clone
сделать неполный:
git clone --depth=1 <remote-url>
# или
git clone --depth=1 <remote-url> --branch <branch_name> --single-branch <folder_name>
Больше опций можно посмотреть в статье от GitHub, а сравнение скорости для некоторых репозиториев — тут (до 25х быстрее).
Еще возникает иногда желание склонировать только коммиты из ветки (например, для того, чтобы проверить каждый из них на вшивость), но, увы, это сложнее. Даже стандартный checkout от GitHub это пока не умеет. Всякие обходные пути можно найти в том же тикете.
Valhalla для примитивов
Хороший доклад про статус проекта Valhalla, который сможет устранить проблемы, связанные с разделением на объекты и примитивы и сопутствующими оптимизациями (хранить данные на стеке).
В начале идет история примитивов, как и почему они появились, зачем нужен int
, когда есть Integer
, а также признаются ранние ошибки первых версий Java. Потом собственно рассказ о том, что с этим можно сделать — и тут всплывают и иммутабельность, и “прозрачные” типы, и null-безопасность, и потокобезопасность, и оптимизации в памяти всякие, и проблема частичной инициализации, и т.д. — то, что обычно рассказывают в каком-нибудь модном ФП языке. Представляю горящие пердаки некоторых джавистов, которые с пеной у рта доказывали что котлин не нужон с этой его проверкой на null и иммутабельностью.
Была веселая история про то, что в первых версиях Java примитивный long
был потоконебезопасен (sic!). Эта история снова может стать актуальной для value-типов на стеке (если они больше машинного слова). Выход — делать все иммутабельно.
История про проблемы с null напоминает историю Kotlin и его платформенными типами (уж не знаю, что хуже, ссылаться на свою статью на хабре или ее репост в бложике), и типичные проблемы с null-безопасностью — а что будет с массивом значений и т.п. В итоге есть план сделать явное обозначение а-ля Integer?
/Integer!
.
Увы, обратная совместимость многому препятствует. Нельзя сделать все не-nullable по умолчанию, Integer!
и int
не получится сделать на 100% синонимами, сериализация вставляет палки в колеса. Есть риск, что Java может превратиться в плюсы с точки зрения синтаксиса (*флешбеки от того, как в C++ записываются лямбды*). Ну и с дженериками еще не все вопросы решены.
В целом выглядит как движение в сторону прогресса, правда очень медленное. Все это продирается через пик сложности — проект начался аж 2014 году. Правильная модель — ключ к успеху, но ее поиски занимают много времени. Слайд с рассмотренными концептами на 44:05 впечатляет. Если отказаться от некоторых «степеней свободы», то куча сложности просто уходит.
Игры в PDF
Тетрис. У меня работает только в десктопных браузерах, хотя в комментах на HN нашли и другие приложения, в которых это пашет. Исходники.
И, конечно, Doom. Работает только в хроме. Исходники.
“Игры прикольные, ситуация страшная”:)
Старейшая тудушка в коде
Ну уж в этом-то году точно все легаси уберем, да?
Чтобы найти старые TODO в репозитории (и, скорее всего, ужаснуться), можно использовать вот эту колбасу
git grep -i -nE 'TODO|FIXME|FIMXE' | while IFS=: read -r file lineno line; do commit_date=$(git blame -L "$lineno,$lineno" --porcelain "$file" | awk '/^author-time/ {print $2}' | { read epoch; date -u -d @$epoch "+%Y-%m-%d %H:%M:%S" 2>/dev/null || date -u -r $epoch "+%Y-%m-%d %H:%M:%S"; }); echo "$commit_date $file:$lineno: $line"; done | tee >(sort > todos.txt)
(результат будет в todos.txt)
P.S. Особым мазохизмом было получение кроссплатформенного варианта этой команды и выдрать нормальную дату из гита, потому что по умолчанию blame
выдавал не очень машиночитаемый формат.
"Кроссплатформенность" bash
Годами сидя на линуксе, особо не задумываешься об версиях баша и стандартных утилит: по умолчанию ожидаешь, что cp
и в Африке cp
, и думать тут много не надо.
Но как только надо написать какой-нибудь не очень тривиальный однострочник, чтобы добавить его в документацию и/или репозиторий, чтобы “работало” везде, сразу возникают проблемы. Например, у какого-нибудь sed
есть как минимум две версии: BSD (во фряхе и маках) и GNU (в большинстве линуксов), и они серьезно отличаются.
Казалось бы, есть POSIX-команды, можно врубить какой-нибудь режим совместимости и все будет пусть и безобразно, но единообразно, да? *падме.жпг* Реальность, разумеется, полна разочарований: так с большинством команд сделать не получится.
Например, GNU date -Is -ud @249499969321
— это BSD date -Iseconds -ur 249499969321
, и если seconds
тоже можно использовать в первом случае, то остальное уже не поменять.
Другой пример: в BSD sed
“на месте” должен быть явным, -i ""
, а в GNU должно быть именно -i
, без явной пустой строки. Обо всяких \b
тоже можно забыть.
Наконец, некоторые вещи можно обнаружить только методом проб и ошибок, например, strftime
в awk
.
Вишенка на торте: по умолчанию на маках стоит баш версии 3.2 аж от 2007 года (пусть даже ее постоянно патчат, функционально она застыла во времени).
В качестве обходного решения на маке можно… тупо поставить GNU-версии через brew
. В среднем по больнице они все равно лучше. Но если это невозможно, то очевидный вариант — обмазать скрипт if/else
с проверками на систему или переписать на питон. Еще один обходной путь: вызывать два варианта команды через ||
с учетом того, что неподходящий вариант отвалится с ошибкой.
Карта исторических границ
Сабж. Для важных переговоров™.
Дублирование ссылки в Markdown
Понадобилось в во внутренней доке вынести часть ссылок в начало документа, чтобы не искать их в тексте. Оказывается, у Markdown есть механизм для ссылки на ссылку! В любом месте документа (например в конце) добавляем название
[link_name]: https://ov7a.narod.ru/index-1.html
И потом используем в квадратных скобках сколько угодно:
Это [ссылка][link_name]. И [это][link_name] та же самая ссылка.
Версионирование
Де-факто стандарт для версионирования всяких библиотек и продуктов — семантическое версионирование. Идеи довольно простые, хотя и полный документ содержит немного душноты.
Браузеры со своими версиями за 300 и внутренние релизы некоторых компаний а-ля 0.192, годами крутящиеся на проде, передают пламенный привет:)
Оказывается, у этого подхода есть куча критиков: 1, 2, 3. Недостатки сводятся к следующему:
- Демагогия по поводу того, “а что такое ломающее изменение”, “а если это влияет только на 1% пользователей”, “а мелкое ли это изменение?”, “это не баг, а фича” и т.п.
- Не все следуют SemVer (sic!) (например, у них 0.x в проде).
- О ужас, SemVer не всем подходит!
- Одно число не может передать всей глубины изменений. На него нельзя полагаться при обновлениях, все равно надо читать список изменений.
- Если ваш продукт последний в цепочке (например, фронтенд-морда) — о боже мой, всем насрать какой он там версии. Это все очень сложно, простоиспользуйте одно число, как например браузеры.
- Частые обновления библиотек могут отпугнуть пользователей.
- Настоящим инженерам вообще версии не нужны — посмотрите на ранние UNIX-программы, они совершенны! Версионирование — это отмазка, чтобы ломать API.
- В большом дереве зависимостей изменение одной версии может привести к каскадному
резонансуизменению заметного числа зависимостей. - Инженеры боятся обновлять мажорную версию своей библиотеки, и откладывают внедрение фич. Иногда во имя маркетинга.
- Ради обратной совместимости приходится делать костыли.
На часть этих замечаний неплохо отвечает создатель спецификации (один из создателей GitHub кстати): не надо бояться увеличивать мажорную версию, не надо мешать маркетинг с техническими деталями, надо любить своих пользователей, предоставляя им средства для автоматических миграций, а ломающие изменения выдавать по чуть-чуть, а не огромными пачками.
В java-мире сейчас обсуждают подход Tip & Tail, который может сгладить некоторые моменты (при этом не противореча идее SemVer). По сути предлагается иметь два релиза: tip, с новейшими фичами и всем таким, и tail, в котором все будет максимально стабильно и меняться очень редко и только когда прям совсем надо (по сути, LTS).
Валидация HTML в консоли
На одной из страничек в легаси проекте всплыл косяк, что есть лишний закрывающий div
. Вроде очевидное решение — его надо убрать, но может можно как-то найти и предотвратить это в будущем? Конечно, для этого можно использовать какой-нибудь JS-фреймворк (какой там сейчас популярный?), но у меня же тупо страничка с шаблоном (или SSR, как сейчас (или уже раньше) было модно говорить). Нашел консольную утилиту — HTML tidy, вы только зацените кислотность сайта! Привлекло, что можно ее можно использовать в формате curl url | tidy
.
P.S. думал еще какой-нибудь плагин/расширение для браузера найти, но это тяжело в пайплайн встроить, и быстро ничего приличного не нашел (если кто шарит, поделитесь опытом).
Применимость AI в разработке
Годная статья про текущий уровень, где автор неплохо и довольно трезво оценил, как лучше сейчас использовать всяких “ассистентов” (демки/MVP, автодополнение, генерация черновых вариантов), какие есть проблемы (код надо проверять, уметь дебажить и думать о крайних случаях оказывается, ну и архитектура с безопасностью в помойке) и попытался посмотреть в будущее (автоматизация рутины, помощь в поиске идей, проактивные предложения ну, и, разумеется, “вкалывают роботы, а не человек!”).
Описанное в статье в целом соответствует моим впечатлениями (см. 1 и 2)