Написать пост

Каждая строка кода должна быть задокументирована

Аватар Типичный программист

Обложка поста Каждая строка кода должна быть задокументирована

Рассказывает Мислав Мароник, автор блога mislav.uniqpath.com

Каждая строка кода должна быть задокументирована, пускай даже не в виде комментариев. Кто бы ни написал четыре строки ниже, он по какой-то причине захотел получить доступ к свойству clientLeft DOM-узла, но не сделал ничего с результатом. Загадочно, не так ли? Можете ли вы сказать, зачем он сделал это, безопасно ли убирать или изменять этот кусок кода в будущем?

			// ...
if (duration > 0) this.bind(endEvent, wrappedCallback)
this.get(0).clientLeft
this.css(cssValues)
		

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

История проекта — его самая ценная документация

Тайну можно раскрыть, посмотрев на комментарий коммита, который изменил эту строку:

			$ git show $(git blame example.js -L 4,4 | awk '{print $1}')
		
Исправление animate() для элементов, только что добавленных в DOMАктивирование CSS-транзакций для элемента, только что добавленного в DOM, не работает в WebKit и Mozilla. Чтобы решить эту проблему, мы сделали так, чтобы каждому присваиванию CSS-свойств предшествовал setTimeout() (смотрите 272513b).Это исправило баг для WebKit, но не для новых версий Firefox. Mozilla требовалось по меньшей мере 15 миллисекунд задержки, что, естественно, неприемлемо.Лучшим решением для обоих движков оказалось активирование «layout». Это можно сделать с помощью получения свойства элемента clientLeft. Есть и другие свойства и методы, которые активируют «layout».

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

Кроме того, выяснилось, что автором этой строки был я. Конечно, я мог написать код лучше: например, инкапсулировать получение свойства в функцию с говорящим именем вроде triggerLayout(), или просто добавить комментарий, зачем здесь вообще нужна эта команда. Тем не менее, в тот день я этого не сделал. Код случается, и он не всегда идеален.

Но даже если код объясняет сам себя или в нем есть комментарии, история проекта может предоставить гораздо больше информации:

  1. Кто добавил этот код.
  2. Когда был добавлен этот код.
  3. Как тестировался этот код (если тестировался вообще).
  4. Документация коммита может быть размером с небольшой роман, в то время как комментарии к коду должны быть максимально короткими.

Да, качество очень важно. Но если вы думаете, как можно улучшить ваш код еще больше, то вам стоит обратить внимание на написание подробных объяснений к коммитам. Стоит требовать это не только от себя, но и от всей вашей команды. Документированная история проекта важна не меньше, чем его отладка.

Исследование истории проекта

git blame

Я уже показывал выше, для чего нужна команда git blame. Даже если у вас нет доступа к репозиторию, вы можете ее использовать, чтобы просмотреть историю любого файла на GitHub.

Особенно удобно это делать с помощью Vim и плагина Fugitive для него:

  1. Введите :Gblame в буфере, чтобы открыть просмотр истории.
  2. Если вам нужно углубиться дальше, нажмите Shift+P, чтобы просмотреть историю родителя коммита.
  3. Нажмите О, чтобы открыть двухпанельный вид и посмотреть выбранный в данный момент коммит.
  4. Введите :Gbrowse, чтобы открыть выбранный коммит в веб-интерфейсе GitHub.
  5. Нажмите gq, чтобы вернуться в главный буфер.
Каждая строка кода должна быть задокументирована 1

Если вам нужна дополнительная справка, введите :help Gblame.

Нахождение pull-запроса, с которого начался коммит

С помощью просмотра истории вы можете получить SHA коммита, но само сообщение, приложенное к коммиту, может и не нести какой-либо полезной информации. Однако если ваша команда использует GitHub Flow, объяснение коммита может быть найдено в обсуждении pull-запроса:

			$ git log --merges --ancestry-path --oneline <SHA>..origin | tail
...
bc4712d Merge pull request #42 from sticky-sidebar
3f883f0 Merge branch 'master' into sticky-sidebar
		

В этом случае SHA коммита было достаточно, чтобы определить, что он взял начало с pull-запроса #42.

Git-pickaxe

Иногда приходится искать что-то пропавшее — например, обращение к функции, которая больше ниоткуда не вызывается. В таком случае лучше всего использовать команду git log с поиском по ключевому слову:

			$ git log -S<string>
		

Таким образом вы можете найти коммит, который, к примеру, убрал вызов определенной функции или добавил новый класс.

git churn

Можно взглянуть на историю проекта, не только подробно изучая один коммит, но также и анализируя изменения в целом. Это делается скриптом git-churn, который использует git log, чтобы собрать статистику о файлах, которые редактировали больше всего. Например, чтобы увидеть, на чем фокусировалась разработка приложения за последние 6 месяцев:

			$ git churn --since='6 months ago' app/ | tail
		

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

Таким же образом можно определить, какие люди ответственны за изменение какой-то части приложения. Например, чтобы определить, кто совершил наибольший вклад в API:

			$ git log --format='%an' --since='6 months ago' app/controllers/api/ | \
    sort | uniq -c | sort -rn | head

 109 Edmond Dantès
  13 Jonathan Livingston
   7 Ebanezer Scrooge
		

 Творение истории

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

  • Пишите комментарии к коммиту так, как будто вы объясняете его коллеге, который сидит рядом с вами и не имеет понятия о том, зачем вы это делаете это. Для начала прочитайте эту статью и при каждом коммите отвечайте на следующие вопросы из нее:
Почему это изменение необходимо?Как оно относится к проблеме?Есть ли у него какие-нибудь побочные эффекты?Добавьте ссылку на обсуждение вопроса.
  • Избегайте в одном и том же коммите изменений, не относящихся к главной проблеме. Если вы заметили опечатку или немного переработали код в том же файле, где делали остальные изменения, сопротивляйтесь искушению смешать их в одну кучу с главной проблемой.
  • Подчищайте историю. Если коммиты еще не были опубликованы, лучше всего убрать из них все лишнее. Все, что изображено на картинке ниже, могло остаться в истории проекта Faraday, но я оставил всего лишь два коммита и исправил сообщения, прикрепленные к ним, чтобы скрыть тот факт, что у меня были проблемы с настройкой скрипта:
  • Придерживайтесь стиля, который бы позволял вам изменять, удалять или добавлять значения из списков, не трогая соседние строки. Вот несколько примеров: var one = "foo" , two = "bar" , three = "baz" // такой стиль позволяет удалить переменную или добавить новую, // не трогая соседние строки # Ruby: result = make_http_request( :method => 'POST', :url => api_url, :body => '...', // Ruby разрешает оставить в конце запятую, ) // тем самым позволяя добавлять/удалять параметры, не трогая остальные

Небольшой бонус

Раз вы дочитали досюда, я награжу вас небольшим скриптом. Он называется git-overwritten и показывает разработчиков, которые вносили изменения в указанную вами ветку:

			$ git overwritten feature origin/master

  28 2014-02-04 1fb2633  Mislav Marohnić: Add Makefile for building and testing
   1 2014-01-13 b2d896a  Jingwen Owen Ou: Add -t to mktemp in script/make
  17 2014-01-07 385ccee  Jingwen Owen Ou: Add script/make for homebrew build
		

Это может быть полезно, когда вы делаете pull-запросы с помощью GitHub Flow и хотите обсудить их с коллегами, но не уверены, кого стоит спрашивать. С помощью этого скрипта вы можете получать имена людей, чьи строки вы собираетесь менять, так что вы будете знать, кого @-упоминать при открытии pull-реквеста.

Перевод статьи «Every line of code is always documented»

Следите за новыми постами
Следите за новыми постами по любимым темам
6К открытий6К показов