Стендап Сьогодні

Що я зробив, що я хочу зробити, і що це все значить.
Повсякденні здобутки в форматі стендапу.
Детальніше в статті

Підписатись на RSS · 📢 Канал в Telegram @stendap_sogodni

06.07.2024

Стискання шрифтів для вебу

Закінчую роботу над значками для Obsidian. Як минулого разу казав, шрифт значків всім гарний, от тільки завеликий за розміром. Взявся обрізати шрифт, щоб залишилася тільки та купка значків, яку я використовую.

На то знайшов бібліотеку fontTools - до речі, ще один продукт на Python, який треба встановлювати на пайтонівський намір. Ну, зате, на щастя, brew install fonttools теж працює. Бо всі ці pip та virtualenv то просто жах.

FontTools вміє багато всього, а мені була потрібна команда subset - вона саме й обрізає шрифти під замовлення. Приклад можна побачити на знімку вище. Взагалі все дуже прямолінійно: даєш шрифт, даєш символи чи їх діапазон — та готово.

Працює навіть надто гарно, бо я довго не міг зрозуміти, чому ж на виході “порожній” файл у 1 кілобайт. Ну не може пʼять значків влазити в 1 Кб! А виходить, що можуть — переконався, коли нарешті наважився перевірити результат на ділі. Тепер мені рішення зі шрифтом для значків подобається ще більше.

Нарешті, тією ж командою можна перекодувати шрифт у WOFF2. Дописав також скрипт, який відразу загортає його в .scss, щоб не робити цього вручну кожного разу, як додам новий значок.


05.07.2024

Тредізація RSS Twitter

Трохи невдала сьогодні спроба. Хотілося у стрічці RSS для Twitter, яку генерує RSSHub, бачити треди в одному пості — бо як окремі пости, їх досить складно сприймати. Взагалі проблема витікає з того, що з API неможливо витягнути твіт, на який зроблена відповідь — тільки його URL. (Та й взагалі той API вже “не той”, та Twitter вже “не той”, та я б із задоволенням про нього забув, проте багато журналістів та дослідників більше нікуди не публікують.)

Ідея була проста: спід час генерації стрічки RSS виявляти ті твіти, що відповідають на інші твіти з того ж RSS, та “підшивати” один до одного. Тут не потрібні додаткові звернення до API - тільки додаткова обробка. Ніби все просто та прототип я навіть зробив, але на практичній перевірці ідея не запрацювала.

Річ у тім, що твітів в одній виборці близько 20, та вони навіть не впорядковані за часом — а, певно, за популярністю чи ще якимсь алгоритмом. Через це у вибірку може потрапити, наприклад, перший та останній твіт у треді — а решта ні. З такого вже кашу не звариш.

Та друга проблема: у вибірку може потрапити не весь тред. Спочатку я думав, що це не так погано — умовно, замість 40 постів в стрічці буде не 1, а 2. Але: при наступному оновленні межі вибірки зсуваються не повністю. Виходить, можна отримати хоч 10 напівдубльованих шматків. Щоб цього уникнути, можна залучити кеш та зберігати попередні пости. Але це вже ускладнення на майбутнє.

До речі, розробляти для RSSHub напрочуд просто; це застосунок Node.js, та запускається він за yarn install && yarn dev. Навіть TypeScript та Prettier в них є. Навіть Codespace підготований! Так що, можливо, власні RSS генератори теж перенесу у RSSHub.


04.07.2024

GitHub Codespaces: на диво гарно!

Сьогодні мав перший досвід роботи у GitHub Codespaces. Це, так би мовити, “хмарне робоче місце”: віртуальна машина з приєднаним редактором, на якій можна вести розробку. Перші враження такі, що це дуже гарне рішення, та якщо вам щось таке потрібне, можна не вагатися.

Перше, що помітиш, це безшовна інтеграція з VSCode. Одна з визначних, хоч і прихованих можливостей VSCode - це клієнт-серверна модель виконання. Тут вона працює на повну, та віддалений проєкт практично не відрізняється від локального. (Єдине, що термінал — не редактор — все ж гальмує, але і тут вони помʼякшили: все введене в термінал моментально зʼявляється “примарними” літерами, а після обробки на сервері вони стають звичайними.)

Зміст проєкту береться з репозиторію GitHub, що очевидно. Також під час створення кодспейсу він питає гілку — а це трохи спантеличило. Але мається на увазі гілка із конфігурацією кодспейсу, яка тут робиться у форматі devcontainer. Далі ми вільні переходити в будь-яку гілку та й взагалі робити, що хочемо. Також можна надати доступ до інших приватних репозиторіїв. Технічно можна навіть створити кодспейс з порожнього репозиторію, а потім підтягнути туди абсолютно інший код.

Всередині отримуємо більш-менш стандартну віртуальну машину з Debian. Головне, що Docker працює. Також маємо можливість доналаштувати, причому, що мені подобається: як спільне для всіх оточення, так і персональне (за допомогою dotfiles). Оце важливий момент: Codespaces це інструмент для команди, тобто досвідчений інженер може налаштувати середовище, яке потім легко запустить будь-хто з колег.

Це приводить нас до питання: кому таке потрібно? Та, як на мене, саме оказійним розробникам. Наприклад, може у вас є підпроєкт, який не всім та не завжди потрібний; можна налаштувати для нього кодспейс та будь-хто з команди зможе долучитися з дрібними змінами. Або інший випадок: для безпеки та ізоляції. Щоб код проєкту та його залежності не потрапляли на локальні диски розробників, вони можуть працювати з ним в кодспейсі. В мене як раз така потреба й виникла, та дуже радий, що я можу майже непомітно перестрибнути у хмарне середовище.

Що тут можна сказати. Microsoft не дарма володіє GitHub, VSCode, та Azure!


03.07.2024

Як запобігти вигорянню на роботі

Поступило питання, яким чином я ще не вигорів на роботі. Ну, давайте так: хто сказав, що не вигорів? Пройшов декілька тестів та отримав результати: від малих до помірних ознак вигоряння. Але за самооцінкою я б сказав, що просто життя зараз складне, тому було б дивно, якщо таких ознак не було.

Що мені допомагає?


02.07.2024

Правило лісника

Сподіваюся, всім відомо правило скаута: залиш місце чистішим, ніж яким його знайшов. Воно доречне як в лісі, так і в коді. Проте для лісника такого правила недостатньо. Лісник також повинен стежити за загальним порядком та створювати сприятливі умови для відвідувачів.

…Щоб не затягувати з метафорою: в команді лісник — це лід інженер. Та лід інженеру мало зробити задачу та переконатися, що всі лінтери проходять. Окрім того, якщо у виконанні зустрілися очевидні перепони, то їх потрібно усунути — або принаймні внести усунення в план.

Наприклад, якщо виправлення помилки показало, що в цьому місці бракує тестів, то потрібно — не писати всі тести за раз — а принаймні підготувати під них базу. Або трапляться що код потребує системного рефакторингу, а кожна окрема задача ніби недостатньо зачіпляє, щоб його робити. Або документацію потрібно написати. Або оновити фреймворк.

Всі ці задачі критично важливі для продукту, та очікувати що обʼємні зміни будуть зроблені “мимохідь” хибно. Або більше, вимагати цього від всіх інженерів. Якщо кожен інженер буде зупиняти заплановану роботу, щоб провести масивний рефакторинг, то темп розробки стане вкрай непередбачуваним.

На то і є головний інженер, щоб уважно стежити за появленням технічного боргу, та робити життя краще для всієї команди.


01.07.2024

Правильний формат адреси бази даних

Здавалось би, це тривіальне питання, але я тільки виринув з масивної зачистки Terraform та вже так не думаю. Найперший вибір — це URL. Причому, URL це не аби що, а рядок, що починається зі схеми… та продовжується на кшталт:

postgresql://myhost.db:1234/mydb?pool=10

URL гарний тим, що в будь-якому середовищі є стандартний спосіб його розібрати. Також це самодостатній формат — в ньому є місце не тільки для адреси, а й для авторизації, додаткових параметрів тощо. Наприклад: потрібно вимкнути TLS для локальної розробки? Це зазвичай можливо без залучення додаткового параметра чи логіки.

Інший раз бачу, параметр називається URL, а всередині пара host:port. Це небезпечно, бо така форма не є URL та призведе до помилки, якщо спробувати її розібрати. Інколи таку пару називають addr, бо вона позначає адресу TCP/IP… або позначала б, якщо замість імені хосту була IP-адреса. Ще є чудовий параметр-сюрприз endpoint. Ця назва взагалі нічого не каже про свій зміст.

На тлі всього цього URL гарний просто тим, що з ним все ясно. А будь-який інший формат, який може захотіти клієнтська бібліотека, можна з нього отримати.

Ще альтернатива: кожний елемент вказувати окремим параметром: host, port, username, password. Це може бути зручно, якщо хост приходить з Terraform, а пароль — зі сховища секретів. Але з інших боків зайві параметри тільки ускладнюють налаштування.


30.06.2024

Власні значки в стилях для Obsidian

В реалізації стилів для канви залишався недолік: для значків я був обмежений символами звичайного шрифту — що незручно ще до того, як згадати, що шрифт може змінюватись. Зміст значка в мене утворюється директивою CSS content. Пробував замінити його на SVG - не зміг редагувати колір того SVG (в межах CSS).

Сьогодні розвʼязав цю задачу остаточно. По-перше, знайомтеся, Nerd Fonts. Це шрифт, в якому зібрано 10 тисяч (!) значків з різних відкритих наборів. Шрифт мене влаштовує краще, ніж SVG, бо з ним можна працювати як зі звичайним текстом. Але тепер, як додати його прямо у CSS?

Виявляється, CSS вміє завантажувати шрифти з data URL. Може, то й очевидно, але я з data URL стикався тільки для зображень. А тут можна отак:

@font-face {
  font-family: "Nerd Fonts Symbols Embedded";
  src: url(data:application/font-woff2;base64,d09... ще мільйон символів);
}

Тільки один нюанс: шрифт розповсюджується в форматі .TTF - це зручно для використання в редакторі, але для Obsidian потрібний шрифт .WOFF2, бо він побудований на вебтехнологіях. Дізнався, що насправді WOFF2 це лише добре запакований TTF, та для перетворення є проста утиліта.

Нарешті, останній момент: щоб використати той значок в CSS, треба писати щось на кшталт content: "\f128"; код символу береться з каталогу. (Або тягнути вбудований CSS Nerd Fonts, але мені то заради пʼяти значків занадто. До речі… сам шрифт пізніше теж можна було б підрізати точно під потребу.)


29.06.2024

Стохастичний таймтрекер та робота

Хоч розробка таймтрекера трохи уповільнилася — але користуюся я ним постійно та веду охайний облік власного часу. От, роздивився, чи може такий облік допомогти для робочих звітів.

(Нагадаю, що стохастичний таймтрекер — на відміну від класичного — питає тебе у випадкові моменти, чим ти займаєшся на той самий час. З одного боку, це не так точно, з іншого боку — не потребує відстежувати кожну активність вручну, та тому краще виявляє відволікання та зміни контексту.)

Почну з очевидного: точних до хвилини звітів тут не вийде. Я б навіть сказав, що в межах одного дня теж нічого конкретного не отримаєш, бо за робочий день можна отримати як два пінги, так і двадцять.

Але чи дійсно такі звіти потрібні, якщо все одно вони агрегуються в статистику на місяць? На такому масштабі стохастичний трекер вже цілком точно вимірює витрачений час.

В минулому я тегував час за субпродуктом та категорією активності (програмування, пошук помилки, комунікація, …) Категорія активності це корисно, субпродукт — не настільки; було б краще тегувати за епіком (навіть напряму — кодом задачі.) В наступному місяці спробую, бо повинно вийти дуже наочно. Також спробую розділяти активності за обовʼязками (наприклад, комунікація — це може бути допомога, чи навпаки пошук допомоги, чи дискусія тощо)

Цікаво побачити, скільки часу уходить на побічні активності; обовʼязки як перегляд PRів здаються такими що відбирають багато часу, але на практиці витрати мінімальні. Хоча це нічого не каже про ментальне навантаження — можливо, в майбутньому почну відстежувати і його рівень.


28.06.2024

Зачистка AWS Parameter Store (та магія jq)

Чудова пʼятнична забава: знайти неавтоматизовані параметри в AWS Parameter Store. В ідеалі, все повинно потрапляти туди через Terraform або іншу автоматику, але ж неодмінно деякі дані протікають вручну.

Очевидно, що вручну я того робити не буду: параметрів за тисячу, це просто нереально. Та також не потрібно. Список параметрів можна отримати через CLI:

aws ssm get-parameters-by-path --path '/' --recursive | jq -r '.Parameters[].Name | sort'

Тут окрім самого AWS CLI використовується утиліта jq. Вона виконує складні перетворення JSON в один рядок; тут ми беремо атрибут Parameters, який є масивом, а з його елементів беремо атрибут Name.

…Тепер за Terraform. Спочатку я хотів шукати кожне імʼя параметра вручну… проте це ще гірше, бо імʼя може конструюватися з відрізків, повторюватись і таке інше. Зате всі параметри сидять в стані. Тобто достатньо стягнути стан та (оскільки це теж JSON) забрати те, що потрібно:

terraform state pull | jq -r '.resources[] | select(.type=="aws_ssm_parameter") | .instances[].attributes.name | sort'

Тут алгоритм складніший, але JQ впорається з тим, щоб знайти ресурс правильного типу.

Залишається тільки порівняти дані командою diff та результат готовий! На жаль, не так легко з’ясувати, які з параметрів дійсно потрібні, а які зайві… зате потім можна згенерувати за шаблоном файл Terraform чи навіть вхідний файл 1Password для секретів.


27.06.2024

Split_tests - швидші збірки на CI

Є в мене стара, але досі корисна утиліта: split_tests. Вона, попросту, розбиває довжелезний запуск тестів на декілька паралельних потоків, за набором файлів. Так збірку довжиною в годину можна виконати навіть за 10 хвилин. (На жаль, підготовка до тестів теж займає час, тому є розумна межа на кількість потоків.)

Для того потрібний тестовий пакет, який на файли можна розбити: наприклад, RSpec, або Mocha (А ось з Go вона ще не працює, хоч на Go написана — бо Go ділить тести на модулі, а не файли.)

(🦀 Як каже аксіома, до моєї реалізації на Go є реалізація з альтернативного всесвіту на Rust: split-test. Ні, серйозно!)

Колись давно я написав цю утиліту для CircleCI. А потім невдовзі там зʼявилася вбудована команда, яка робить те саме. Потім я опинився на GitHub Actions, та утиліта знову стала до нагоди — альтернатив тут немає, а ті що є, написані або на основі моєї утиліти, або схожих.

Як воно працює. Зрозуміло що ми хочемо досягнути рівного часу виконання на кожний потік. Прийнятного результату дає розділення файлів за кількістю рядків. Звісно, трапляються аномалії, де тривалість не корелює з довжиною. Тому також можна розділяти за історичними даними за тривалістю кожного тесту. Але тоді потрібно ті дані зберігати.

Або, можна знайти аномалії вручну та викликати їх окремо. Оце на мою думку оптимальний варіант. І технічно просто, і результат надійний. Зазвичай ті “аномалії” виявляються величезними інтеграційними тестами та їх в застосунку лише декілька.