Comments 31
Разработчиков не радовало, что из-за таких пустяков приходилось возвращаться к задаче. Тем более что несвоевременно влитый merge request это ещё и merge с новыми изменениями, сделанными другими.
На проекте работала распределенная команда: часть — на стороне Promwad, часть — на стороне заказчика. Поэтому в рамках этой конкретной разработки мы договорились использовать общий инструмент для более простого и удобного форматирования.
Сейчас разработчики просто коммитят свой код, не заботясь о том, правильно ли там расставлены пробелы с переносами. Проблемы возникают только при ошибках форматера, но их гораздо проще обойти при коммите, чем потом ловить замечания от Lead-ов. :-)
Пытался использовать clang-format но он не работал с переносами строчек нормально. Была у меня из Qt функция connect
принимает 4 аргумента: sender, signal, receiver, slot. Все четыре не помещались в строчку, тогда я сделал так
connect(sender, signal,
receiver, slot);
Запустил шланг и он мне выдал такое уродство:
connect(sender, signal, receiver,
slot);
Не вижу принципиальной разницы между этими двумя уродствами. Если параметры не умещаются в одну строку или если они не тривиальные, то лучше каждому параметру выделить отдельную:
connect(
sender,
signal,
receiver,
slot,
)
после каждой запятой делать перенос, не всегда удобно. В другом примере у меня были сгруппированы по логике елементы массива в несколько строчек, а он из них сделал матрицу 2x4. Я так и не нашёл как это настраивается.
// clang-format off
... My beautiful something ...
// clang-format on
Касательно переносов и прочего форматирования — день поработать с автоформатированием, включённым при сохранении файла ( Qt Creator так умеет) — вообще перестаёшь задумываться над форматированием.
Я пишу жуткую фигню как придётся, потом жму сохранить и раз — красивый код, сколько там трудов ушло на расставление переносов — знать не знаю.
Мне это на столько удобно, что трюк выше я пока использовал всего один раз когда цланг портил колонки данных в константе, при этом в случае массива объектов он неплохо справляется с форматированием.
А какой используете .clang-format файл?
Да, clang-format никогда не научится понимать, что какие-то параметры тесно связаны между собой — ну и фиг с ним. Лучше выставить ширину строки где-нибудь на 100-120 символов и всё: случаев, когда вызов функции с четырьмя аргументами перестанет помещаться в строку, станет меньше — и их уже можно будет терпеть переформатированными в столбик.
Например:
connect(this, &ColorListWindow::colorChanged,
mapper, &QDataWidgetMapper::submit);
Cтиль пробовал просто от Google.
int main() {
connect(this, &ColorListWindow::colorChanged, mapper,
&QDataWidgetMapper::submit);
}
Это потому что в конфиге от гугла есть: ColumnLimit: 80
Не вижу ничего ужасного тут, всё вполне логично. Длинные строки кода надо переносить ибо это нечитаемо.
Если у вас другое мнение на этот счёт, изучайте опции конфига clang-format. Насколько помню, там можно разрешить ручной перенос аргументов функции на разные строки.
Я с самого начала о том и писал что он поменял расположение переноса.
connect(this, &ColorListWindow::colorChanged,
mapper, &QDataWidgetMapper::submit);
Хотя файл официальный, но после форматирования code review пройти не возможно ;) Пришлось его при сохранении отключить, где настроить данные параметры тоже не нашёл, хотя просмотрел всю документацию по clang-format.
Возможно, вам надо форматировать diff кода перед тем как коммитить его
git diff -U0 --no-color | clang-format-diff-6.0 -i -p1
если под Linux. Или git-clang-format уже после коммита. Далее смотрите изменения форматера и git commit --amend --no-edit (Хотя сам не пробовал так)
Хотя файл официальный, но после форматирования code review пройти не возможно ;)А вы пробовали? Обычно если в проекте начинают использовать clang-format, то претензии к расстановке пробелов больше в code review не рассматриваются: как clang-format отформатировал — так и будет.
Иначе в нём и смысла-то никакого нет: зачем нужен clang-format, если он время не экономит?
Имхо опасно делать такие pre-commit hook.
Во-первых, вы должны абсолютно доверять clang-format и молчаливо считать, что его переформатирование абсолютно всегда правильно (готовы это гарантировать? Вообще для любого кода?) Во-вторых, бывают случаи, когда нарушение стиля кода — вынужденная мера. В вашем же случае автор коммита даже не узнает про то, что его код был переформатирован.
Более корректное решение: Hook должен отклонять неподходящий коммит. После чего происходит 1 из 2 вещей: а) автор переформатирует код clang-овским или любым другим тулом и отправляет повторно (он также может заранее попытаться реализовать автоформатирование на своей стороне): б) автор доказывает необходимость ошибки форматирования, и коммит разрешается в административном порядке.
В вашем же случае автор коммита даже не узнает про то, что его код был переформатирован.
Неправда. Там выводиться либо «Nothing to be formatted» либо полный diff форматера. Исключение может быть только в GUI утилитах, которые не показывают вывод git commit.
Более корректное решение: Hook должен отклонять неподходящий коммит.
На практике, в pipeline -ах сервера где делают code review(gitlab например), надо показывать что для .clang-format проекта есть diff в рассматриваемом коммите. Тогда, тот кто делает review решает что дальше.
Есть ли какой-нибудь способ объяснить ему несколько допустимых вариантов форматирования?Это опции конфига начинающиеся с «Allow». В вашем случае AllowAllParametersOfDeclarationOnNextLine
clang.llvm.org/docs/ClangFormatStyleOptions.html
Хотя иногда, как в примере выше с technic93 это может не работать.
Вообще, составление конфига для ClangFormat это бег по граблям и поиск компромиссов. Надо время и терпение.
Форматирование исходного кода в Linux средствами ClangFormat: проблемы и решение