Перейти к содержанию
Авторизация  
xuser

Автоматическая проверка стиля джава кода перед коммитом (git + ruby + checkstyle).

Рекомендуемые сообщения

Для валидации стиля джава кода есть библиотека checkstyle используется обычна так:

java -jar path/to/checkstyle.jar -c path/to/checks.xml path/to/file

В качестве пути до checks.xml можно использовать как реальный путь в файловой системе так и одно из двух внутренних значений:

/sun_checks.xml
/google_checks.xml

Но запускать вручную проверку перед каждым коммитом не удобно и легко забыть на помощь нам приходят система хуков (перехватчиков). В случае с git в качестве хука может использоваться любой скрипт/бинарник поддерживаемый вашей системой. В моём примере это скрипт на руби. Так-как мы хотим выполнить валидацию кода перед коммитом то лучше всего нам подходит хук pre-commit. Если выполнение хука завершается с не нулевым статусом коммит отменяется. Создаём в поддирректории .git/hooks нашего репозитория файл pre-commit со следующим содержимым:

#!/usr/bin/env ruby

require 'stringio'
# redirrect outpit to stderr
$stdout = STDERR

# run shell command with stderr reddirection
# and strip tralling spaces, etc from it's output
def run(command)
  `#{command} 2>/dev/null`.strip
end

# change dirrectory to repository root
Dir.chdir(run('git rev-parse --show-toplevel'))

# config = '/google_checks.xml'
config = run('git config --get checkstyle.config')
# jarpath = '/usr/share/checkstyle/checkstyle.jar'
jarpath = run('git config --get checkstyle.jarpath')
# java binary in path so not need in absolute path
javacmd = run('git config --get checkstyle.javacmd')

# set javacmd to java when it empty
javacmd = 'java' if javacmd.empty?
# display error message when config variables not set
if config.empty? || jarpath.empty?
  puts 'pre-commit: Stopping commit because of errors.'
  puts 'To use this script you need set following variables:'
  puts '  git config [--global] checkstyle.config path/to/checks.xml'
  puts '  git config [--global] checkstyle.jarpath path/to/checkstyle.jar'
  puts "\npre-commit: You can bypass this check using `git commit -n`"
  # exit with non zero exit code to abort commit
  exit 1
end

# iterate over files staged for commit
run('git diff --cached --name-only --diff-filter=ACM').lines.each do |f|
  # skip non java files
  next unless /^.*\.java$/ =~ f

  # run code style check for current file and delete constant lines from it's output
  # use 'bash -c' because java may be not in PATH enviroment variable used by sh
  message = `bash -c '#{javacmd} -jar #{jarpath} -c #{config} #{f}' 2>/dev/null`
            .gsub(/(?:Starting audit\.{3}|Audit done\.)/, '').strip

  # if no message go to next file
  next if message.empty?
  # reformat and display message
  puts 'pre-commit: Stopping commit because of errors.'

  puts "Errors in file: #{f}"
  message.lines.each do |l|
    # use regex to get needed values from line
    /^\[(\w+)\] .*\.java:(\d+)?:\d+? (.*)$/i.match(l) do |m|
      # use values found by regex to create reformated line
      puts "  line #{m[2]} #{m[1].downcase}: #{m[3]}"
    end
  end

  puts "\npre-commit: You can bypass this check using `git commit -n`"
  # exit with non zero exit code to abort commit
  exit message.lines.count
end

Далее настраиваем параметры:

git config checkstyle.config path/to/checks.xml
git config checkstyle.jarpath path/to/checkstyle.jar

Так-как скрипт написан на руби то интерпретатор руби должен быть установлен в системе. Теперь перед коммитом джава файлы буду проверятся с помощью checkstyle аатоматически, а при нахождении ошибок коммит будет отменён и соответствующее сообщение выведено на экран. Более подробную информацию про хуки в git можно найти тут.
 
Вот как это выглядит:
thumb_pre_1487763342__screenshot_2017022

 

Обновлено: Добавил комментарии для тех кто не знает руби.

 

Вопрос: Интерусует ли подобная информация кого-нибудь на этом форуме? В планах написать общий хук на руби или баше который будет запускать другие хуки к примеру 1н для валидации java исходников, 2й для валидации xml итд. Возможно интеграция с существующим гемом pre-commit, а может полностью свой велосипед :). Насколько получится незнаю так-как изучать хуки стал только вчера, да и других дел много.

 

PS: писалось и тестировалось под линуксом и будет ли работать в винде понятия не имею :rofl:. Подобные хуки поддерживают и другие системы контроля версий такие как svn, mercurial итд. Описываю на примере git потому что сам только его и использую.

Изменено пользователем xuser
  • Upvote 1

Поделиться сообщением


Ссылка на сообщение
Поделиться на другие сайты

Для публикации сообщений создайте учётную запись или авторизуйтесь

Вы должны быть пользователем, чтобы оставить комментарий

Создать учетную запись

Зарегистрируйте новую учётную запись в нашем сообществе. Это очень просто!

Регистрация нового пользователя

Войти

Уже есть аккаунт? Войти в систему.

Войти
Авторизация  

  • Последние посетители   0 пользователей онлайн

    Ни одного зарегистрированного пользователя не просматривает данную страницу

×
×
  • Создать...