Предыстория - Из-за бизнес-требований нам необходимо поддерживать прототип хранилища для определения структуры данных для внешних и внутренних студентов.Однако в процессе использования хранилища часто возникает ошибка формата файла прототипа, что приводит к в краше на соответствующей странице системы. Поэтому мы намерены включить схему проверки перед фиксацией в прото-репозитории, чтобы снизить вероятность таких событий.
Что такое предварительная фиксация?
Возможно, вы не знакомы с предварительной фиксацией, но мы в основном наслаждались удобством, которое она приносит. Предварительная фиксация — это хук, поставляемый с Git, который может просматривать, обнаруживать или выполнять другие операции с отправленным контентом до того, как мы совершим фиксацию.
Чтобы дать один из наиболее распространенных примеров, при разработке проектов JS, если мы используем леса, предоставляемые сообществом, Eslint обычно предоставляется, а затем мы можем не отправлять код, потому что некоторые стили кода не соответствуют спецификации ESLINT. Отказ
Это то, что вы можете сделать с предварительным конфигом, что обеспечивает последовательный стиль кода в репозитории. Глядя на документацию Git, вы можете знать, что GIT не только обеспечивает крючки в фазе коммиты, но также подготовит-Compad-MSG, Post-Compart, Pre-Rabasa ... Есть соответствующие крючки практически на каждом этапе от отправки кода Нажатие кода, мы можем вызвать спрос.
Как активировать предварительную фиксацию (как активировать Git Hook)
В корневом каталоге каждого репозитория git есть скрытая папка .git, а внутри есть папка с именем «hooks». Как следует из названия, эта папка используется для хранения различных хуков. После входа вы обнаружите, что есть много файлов с суффиксом .sample. Это шаблоны ловушек, которые поставляются с git. Есть несколько встроенных случаев ловушек для вашей справки. После того, как мы напишем собственный метод ловушки, нам нужно только добавить . образец Суффикс можно удалить.
Совет: любой исполняемый скрипт с правильным названием будет работать нормально — вы можете написать его на Ruby, Python или любом другом языке. --Пользовательский Git — хуки Git
Как написать удобный хук-скрипт
- Определить целевой файл
Перед выполнением проверки проверка должна сначала убедиться, что целевой файл (файл изменен или добавлен). Изменить список и добавить файл мы можем узнать методами git diff.
#!/bin/bash
STAGE_FILES=$(git diff --cached --name-only --diff-filter=ACM -- '*.proto')
if [[ $STAGE_FILES = "" ]] ; then
echo "无需要检查的proto文件"
exit 0
fi
- прочитать содержимое файла
Если в измененном файле есть файл proto, он войдет в следующий процесс. Сначала мы распечатываем файл обнаруженных изменений для подтверждения отправителем, а затем проходим процесс проверки.
echo "$STAGE_FILES 待检查"
for proto in $STAGE_FILES;do
PROTO_TEXT=$(cat $proto)
echo "$proto 检查中..."
done;
exit 0
- Отправьте содержимое файла на сервер
request=`curl -s -H "Content-type: application/json" -H "X-Proto-Commit: precommit" -X POST -d '{"proto_text":"'$PROTO_TEXT'","name":"'$proto'"}' http://localhost:7777/api/proto/preCommit`
- Обработка возврата сервера
STATUS=`echo -e "'$request'" | grep "error"`
if [[ $STATUS = "" ]];then
echo "$proto 检查完成..."
else
echo $STATUS
exit 1
fi
Мы будем использовать список измененных файлов, полученный на первом шаге, в качестве тела цикла, считывать содержимое каждого измененного прото-файла и отправлять его на сервер, отвечающий за обеспечение возможностей обнаружения через curl, и ждать, пока сервер вернет результат теста. .
Кажется, что простая возможность pre-commit-proto завершена, но при реальном использовании обнаруживается, что некоторые прото-файлы, отправленные на сторону обнаружения, обязательно сообщат об ошибке, даже если в самом файле нет ошибок, сервер все равно будет Возвращает ошибку.
После многих тестов мы, наконец, обнаружили проблему формата кодирования.Поскольку собственная функция кодирования curl имеет ограниченную поддержку китайского языка, мы решили загрузить весь прото-файл на сервер для тестирования, чтобы убедиться, что обнаруженный контент абсолютно корректен.
Как загрузить прото файл и проверить его через curl?
Поскольку метод прямого чтения содержимого push-файла не может дать нужного эффекта, мы пытаемся загрузить весь прото-файл на сервер для парсинга.
- request=`curl -s -H "Content-type: application/json" -H "X-Proto-Commit: precommit" -X POST -d '{"proto_text":"'$PROTO_TEXT'","name":"'$proto'"}' http://localhost:7777/api/proto/preCommit`
+ request=`curl -k -s -F "file=@$proto" http://localhost:7777/api/proto/preCommit`
Нам нужно только настроить оператор выполнения после переменной запроса, чтобы загрузить прото-файл в указанное место. Есть несколько параметров, на которые стоит обратить внимание:
- -F: Используется для загрузки бинарных файлов на сервер.
- -k: указывает пропустить проверку SSL. (Необязательно, добавлено, потому что в примере это не https-интерфейс)
- -s: беззвучный режим, ничего не выводить (опционально, смотрите сами)
После того, как файл успешно загружен, задача стороны отправки кода завершена, а остальное — увидеть результат обнаружения на стороне сервера. Если тест пройден, выйдите из предварительной фиксации и продолжите отправку действия, иначе он предложит неправильную часть прото-файла и прервет отправку кода.
Как включить предварительную фиксацию в новом клоне
В этот момент у всех все еще может быть большой вопросительный знак. Основная идея этой статьи — изменить содержимое папки .git, но, поскольку это проект git, это должно означать, что его могут запускать и другие люди, кроме вас. В этом случае предварительная фиксация будет недействительной. Поскольку папка .git является локальной и не может храниться в репозитории, мы используем другой метод для загрузки написанного скрипта предварительной фиксации в его локальный .git/hooks.
#!/bin/bash
cp pre-commit .git/hooks/pre-commit
chmod 777 .git/hooks/pre-commit
echo 'protobuf预检初始化完成'
exit 0
Давайте прочитаем приведенный выше блок кода построчно, начиная с объявления bash-скрипта. Затем скопируйте файл «pre-commit» в корневой каталог проекта по указанному пути «.git/hooks/pre-commit».
Это еще не конец.Если права доступа к файлу не изменены, мы обнаружим, что хук по-прежнему не срабатывает при фиксации git, поэтому измените «.git/hooks/pre-commit» на 777 (доступно для чтения, записи и выполнения).
постскриптум
На этом разработка и срабатывание простого хука pre-commit завершены, и использование других хуков, предоставляемых git, аналогично, нам нужно только выбрать хук, который соответствует потребностям, а затем заменить разработанный скрипт на папка крючки. Полный код прикреплен ниже ~
init.sh
#!/bin/bash
cp pre-commit .git/hooks/pre-commit
chmod 777 .git/hooks/pre-commit
echo 'protobuf预检初始化完成'
exit 0
pre-commit.sh
#!/bin/bash
STAGE_FILES=$(git diff --cached --name-only --diff-filter=ACM -- '*.proto')
if [[ $STAGE_FILES = "" ]] ; then
echo "无需要检查的proto文件"
exit 0
fi
echo "$STAGE_FILES 待检查"
for proto in $STAGE_FILES;do
PROTO_TEXT=$(cat $proto)
echo "$proto 检查中..."
request=`curl -k -s -F "file=@$proto" http://localhost:7777/api/proto/preCommit`
CODE=`echo -e "'$request'" | grep "code" | awk -F ":" '{print $2}' | awk -F "," '{print $1}'`
if [[ $CODE > 0 ]];then
echo "预查服务故障,请重试"
exit 1
fi
STATUS=`echo -e "'$request'" | grep "error"`
if [[ $STATUS = "" ]];then
echo "$proto 检查完成"
else
echo $STATUS
exit 1
fi
done;
exit 0