Перейти до вмісту

Блог ·

Документація, написана до злиття

Два речення на новій сторінці документації стали хибними того ж дня, бо раніше злилася інша гілка. Що ловить сторожа, а що лише grep.

Автор: Provibr

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

За один раунд ми написали дві нові сторінки документації: одну для редактора автоматизації, близько 2930 англійських слів у восьми розділах, і одну для панелі приладів, близько 909. Плюс розділ, доданий до двох сторінок, що вже існували. Два речення на сторінці автоматизації були хибними вже тоді, коли її випустили.

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

Речення, яке було правдивим, коли його писали

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

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

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

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

Що може вловити сторожа

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

Сторінка панелі приладів має таблицю з переліком карток, які користувач може додати. Ці картки мають назви девʼятьма мовами, і ці назви вже існують: вони є написами у виборнику, який користувач і натискає. Написати таблицю в документації означає написати їх удруге.

Схибило це негайно, у першій чернетці, англійською:

У виборникуНа сторінці документації
Integration listConnections
Open ticketsTickets
Credit balanceCredit

Жодне з них не є хибним як англійська. Усі три є хибними як документація, бо читач, якому сказали додати «Connections», шукатиме картку під назвою Connections і знайде картку під назвою Integration list. Розходження є мовчазним за побудовою: обидва тексти самі по собі добрі, і ніхто не кладе посібник поруч із виборником.

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

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

Технічний токен не є словом

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

Поставити елемент <code> буквально всередину масиву рядка таблиці означає зачепити правило лінтера, яке хоче ключ на кожному елементі JSX у масиві, навіть тут, де складова таблиці загортає кожну комірку у власний елемент із ключем, а сам ключ ніколи не читається. Поставити на нього ключ означає зачепити іншу сторожу, яка бачить дитину з ключем поруч із викликами перекладу, чиї ключі вона в тому файлі розвʼязати не може.

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

Знімки екрана, що виглядали успішними

Вимірювання цих сторінок містило знімки за якорями: прокрутити до кожного розділу, сфотографувати його, подивитися на нього.

Девʼять із них показували шапку сторінки.

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

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

Частина, до якої не дістає жодна сторожа

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

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

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

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

Що ми б записали

  1. Проза про код є неперевіреним твердженням. Ніщо у збірці її не читає. Це нормально, доки всі це знають і ніхто не припускає, що зелений запуск каже щось про абзац.
  2. Документацію пишуть проти гілки, а не проти main. Якщо інші раунди відкриті, сторінка є знімком стану, який може ніколи не вийти. Перечитайте її після злиття, а не до нього.
  3. Назву, що існує в продукті, слід читати, а не набирати заново. Три з шести назв карток розійшлися вже в першій чернетці. У девʼяти мовах це є класом помилок, а не випадковістю.
  4. Виводьте ключ документації з ідентифікатора. Тоді наступна картка буде покрита без того, щоб хтось памʼятав це правило.
  5. Вгадане слово в мові, якої ви не читаєте, є невидимим. Пʼять мов мали вгадані назви кнопок, і червоного не було нічого.
  6. Переклад назви продукту є зіпсованою вказівкою. Якщо меню каже Scripts у кожній мові, посібник каже Scripts у кожній мові.
  7. Коли два правила лінтера не сходяться, запишіть, якого ви послухалися і чому. Альтернативою є коментар-вимкнення, який згодом ніхто не зможе оцінити.
  8. Вимірювання, що при невдачі видає правдоподібний результат, не поставлять під сумнів. Фотографуйте те, що ви можете впізнати, і дивіться на знімки.

Для ясності про те, чим це є: обидві сторінки працюють девʼятьма мовами, два застарілі речення виправлено в усіх девʼяти, а сторожа над назвами карток стоїть у наборі тестів і була доведена червоною раніше, ніж зеленою. Твердження на сторінках походять із читання коду, а не з його запуску; приклад із curl на сторінці автоматизації ніколи не стріляли в живу кінцеву точку; і кожен переклад мав одного читача, а не двох.

Із платформної роботи над Provibr. Картки, на які посилаються ці назви, описано в ярлик є посиланням, а не правом, а чого коштує тримати девʼять каталогів чесними, описано в шістнадцять тисяч ключів, девʼять мов.

Читати далі

Почніть з одного хоста й одного агента

Створіть обліковий запис, встановіть агента однією командою та підключіть свій перший хост Proxmox. Пробний період триває 14 днів і не потребує платіжних даних.