Уведомления

Группа в Telegram: @pythonsu

#1 Авг. 5, 2009 20:49:38

sober
От:
Зарегистрирован: 2009-07-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

Какой клиент используете? Может дело в нем?
Давайте свой репозиторий, попробую у себя воспроизвести. Только из-за ваших виндовых штучек типа этого: ‘src\\’, ‘checkstyle\\checkstyle_errors.xml’ и подобных мне нужно будет править код, чтобы оно хоть как-то заработало. Так что если можно, то сделайте это платформо-независымым, плз.

Да, я уже писал об этом, но вы видимо пропустили:
svn://localhost/ - не лучший метод для работы локально, по-моему. Для этого есть file://
Клиент - svn-1.6.3 (Subversion Win32 binaries for Apache 2.2.x)
Скрипт, исправлю, но репозиторий, к сожалению могу использовать только локальный, если Вас это не остановит, готов предоставить архив со всем необходимым, включая датасет для тестирования. :)



Офлайн

#2 Авг. 6, 2009 10:22:38

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

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



Отредактировано (Авг. 6, 2009 10:25:07)

Офлайн

#3 Авг. 6, 2009 18:02:15

sober
От:
Зарегистрирован: 2009-07-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

Проблема в том, что клиент молча отваливается при попытке записать в sys.stderr длинный лог. Скрипт исправил:

"""
A subversion pre-commit hook that validates the commited files for
checkstyle violations.
"""

__authors__ = [
# alphabetical order by last name, please
'sober',
]

import logging
import os, sys
import pysvn
import re
import shutil
import subprocess as subp
from xml.dom import minidom

# directory in which this script is located
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
SVN_CLIENT = pysvn.Client()

# setup LOGGER
LOGGER = logging.getLogger(__name__)
FORMATTER = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
FILE_HANDLER = logging.FileHandler(os.path.join(CURRENT_DIR, 'pre-commit.log'), mode='w')
FILE_HANDLER.setFormatter(FORMATTER)
LOGGER.addHandler(FILE_HANDLER)
LOGGER.addHandler(logging.StreamHandler())

def prepare_dir(filename):
""" Creates directory tree if not exists """
dir_path = os.path.dirname(filename)
if not os.path.exists(dir_path):
os.makedirs(dir_path)

def clean_dir(path):
""" Removes all content of the specified directory """
if os.path.exists(path):
shutil.rmtree(path, True)
os.makedirs(path)
else:
raise OSError('The system cannot find the file specified: \'%s\'' % path)

def get_expanded_path(path, root=None):
"""Returns expanded, local, native filesystem working copy path.

Args:
path: path to expand and convert to local filesystem directory separators
root: if present, prepended to path first
"""
path = path.replace('/', os.sep)
if root:
path = os.path.join(root.replace('/', os.sep), path)

return path

def run_checkstyle(path):
""" Executes checkstyle validation as the separate process
which executes the Ant checkstyle task

Args:
path - path that should be checked
"""
cmd = 'ant -Dcheck.dir=%s' % path
proc = subp.Popen(cmd, shell = True, stdout = subp.PIPE, stderr = subp.STDOUT, cwd=CURRENT_DIR)
proc.communicate()

def export_repos_files(changes, path):
""" Exports committed files from transaction to the specified path
Args:
changes - list of changed files
path - root destination of the files being exported
"""
export_list = {}
for entry in changes:
src = ''.join(['svn://localhost/', entry])
dest = get_expanded_path(entry, root=path)
export_list[src] = dest

for src in export_list:
dest = export_list[src]
prepare_dir(dest)
SVN_CLIENT.export(src, dest)

def get_checkstyle_report(path):
""" Returns checkstyle report as a dictionary which contains amount
of checkstyle violations for every file
Args:
path - path to the checkstyle report
Returns:
dictionary which contains amount of checkstyle violations for every file
"""
report = {}
xmldoc = minidom.parse(path)
file_tags = xmldoc.getElementsByTagName('file')
for tag in file_tags:
key = tag.getAttribute('name')
value = len(tag.getElementsByTagName('error'))
if key in report:
report[key] += value
else:
report[key] = value

return report

def main (repos, txn):
""" Hook entry point """

# magic keyword which allows to skip checkstyle
checkstyle_pattern = '.*skipcheckstyle.*'
# directory which should contain files to be checked
check_dir = os.path.join(CURRENT_DIR, 'src')
# path to the checkstyle report
errors_report_path = os.path.join(CURRENT_DIR, 'checkstyle/checkstyle_errors.xml')
# maximum capacity of errors in report
max_error_cnt = 25

trans = pysvn.Transaction(repos, txn)

# checking the value of 'skip.checkstyle' option (set in the commit log)
log_msg = trans.revpropget('svn:log')
if re.search(checkstyle_pattern, log_msg):
LOGGER.info('skipping checkstyle')
sys.exit(0)

changes = trans.changed()
all_changes = []
modified = []

for path in changes:
if path.endswith('.java'):
status = changes.get(path)[0]
if status is not 'D':
all_changes.append(path)
if status is 'R':
modified.append(path)

if all_changes:

# preparing check dir
if not os.path.exists(check_dir):
os.makedirs(check_dir)
else:
clean_dir(check_dir)

# recieving contents of the files
for path in all_changes:
file_path = get_expanded_path(path,root=check_dir)
prepare_dir(file_path)
f = file(file_path, 'w')
f.write(trans.cat(path))
f.close()

#LOGGER.info('Executing checkstyle over committed files ...')
run_checkstyle(check_dir)

cur_report = get_checkstyle_report(errors_report_path)
clean_dir(check_dir)

export_repos_files(modified, check_dir)
#LOGGER.info('Executing checkstyle over repository versions of commited files ...')
run_checkstyle(check_dir)
prev_report = get_checkstyle_report(errors_report_path)

errors = []
cur_errors = 0
msg_pattern = 'The checkstyle violations amount in file \'%s\' has increased from %s to %s'
for path in cur_report:

if len(errors) < max_error_cnt:
cur_errors = cur_report[path]

if path not in prev_report and cur_errors:
errors.append((msg_pattern % (path[len(check_dir):], '0', cur_errors)))

elif prev_report[path] < cur_errors:
errors.append((msg_pattern % (path[len(check_dir):], prev_report[path], cur_errors)))
else:
pass


if errors:
LOGGER.error('\nCheckstyle violations amount in committed files has exceeded:\n')
for e in errors:
LOGGER.error(e)

return 1

if __name__ == '__main__':
if len(sys.argv) < 3:
sys.stdout.write("\nUsage: %s REPOS TXN\n" % (sys.argv[0]))
else:
sys.exit(main(sys.argv[1], sys.argv[2]))
Самым интересным и неожиданным оказалось то, что скрипт работает некорректно в случае с несколькими одновременными коммитами. Оказалось, что хук скрипты выполняются асинхронно, таким образом, результаты проверок получаются неверными. Кто-нибудь знает, есть ли возможность как-то контролировать порядок выполнения хуков?



Отредактировано (Авг. 6, 2009 18:08:16)

Офлайн

#4 Авг. 6, 2009 20:54:16

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

sober
Проблема в том, что клиент молча отваливается при попытке записать в sys.stderr длинный лог.
Вот мой тестовый скриптик:
#!/usr/bin/env python

import sys
import pysvn

def hook(repo, trn):
trans = pysvn.Transaction(repo, trn)
for path, props in trans.changed().iteritems():
if props[1] == pysvn.node_kind.file:
sys.stderr.write('content of %s: %s\n' % (path, trans.cat(path)))
sys.stderr.write('very long string' * 1000000)
return 1

if __name__ == '__main__':
sys.exit(hook(*sys.argv[1:]))
Прекрасно вывел мне 16000186 байт и ничего не сказал. Нужно больше?


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



Офлайн

#5 Авг. 6, 2009 21:02:11

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

sober
Скрипт исправил
Вот, что говорит pylint про ваш скрипт, если вам лень запустить :):

C: 25: Line too long (89/80)
C: 26: Line too long (89/80)
C: 43: Line too long (82/80)
C: 66: Line too long (99/80)
C:115: Line too long (86/80)
C:162: Line too long (91/80)
C:168: Line too long (99/80)
C:175: Line too long (91/80)
C:178: Line too long (105/80)
C:184: Line too long (93/80)
R:107:main: Too many local variables (21/15)
C:149:main: Comma not followed by a space
file_path = get_expanded_path(path,root=check_dir)
^^
C:151:main: Invalid name “f” (should match {2,30}$)
C:185:main: Invalid name “e” (should match {2,30}$)
R:107:main: Too many branches (16/12)

Если о ‘line too long’ и всяких ‘too many …’ можно с натяжкой сказать, что стиль у вас такой, то ‘Comma not followed by a space’ и ‘invalid name’ нужно исправлять по-любому.



Офлайн

#6 Авг. 7, 2009 12:49:11

sober
От:
Зарегистрирован: 2009-07-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

Ed
Прекрасно вывел мне 16000186 байт и ничего не сказал. Нужно больше?
У меня под linux тоже этой проблемы не было, не знаю с чем это связано …

Ed
Используйте временный каталог, либо просто добавьте номер транзакции - получите уникальное имя. Также проверьте, чтобы логи и другие файлы, которые вы используете были уникальными, вот и будет вам асинхронность.
Точно! Как я сам не додумался…

"""
A subversion pre-commit hook that validates the commited files for
checkstyle violations.
"""

__authors__ = [
# alphabetical order by last name, please
'sober',
]

import logging
import os, sys
import pysvn
import re
import shutil
import subprocess as subp
from xml.dom import minidom

# directory in which this script is located
CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
SVN_CLIENT = pysvn.Client()

# setup LOGGER
LOGGER = logging.getLogger(__name__)
FORMATTER = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')


LOGGER.addHandler(logging.StreamHandler())

def prepare_dir(filename):
""" Creates directory tree if not exists """
dir_path = os.path.dirname(filename)
if not os.path.exists(dir_path):
os.makedirs(dir_path)

def clean_dir(path):
""" Removes all content of the specified directory """
if os.path.exists(path):
shutil.rmtree(path, True)
os.makedirs(path)
else:
raise OSError('The system cannot find the file specified: \'%s\'' % path)

def get_expanded_path(path, root=None):
"""Returns expanded, local, native filesystem working copy path.

Args:
path: path to expand and convert to local filesystem directory separators
root: if present, prepended to path first
"""
path = path.replace('/', os.sep)
if root:
path = os.path.join(root.replace('/', os.sep), path)

return path

def run_checkstyle(path, log_path):
""" Executes checkstyle validation as the separate process
which executes the Ant checkstyle task

Args:
path - path that should be checked
"""
cmd = 'ant -Dcheck.dir=%s -Dlog.path=%s' % (path, log_path)
proc = subp.Popen(cmd, shell = True, stdout = subp.PIPE, \
stderr = subp.STDOUT, cwd=CURRENT_DIR)
proc.communicate()

def export_repos_files(changes, path):
""" Exports committed files from transaction to the specified path
Args:
changes - list of changed files
path - root destination of the files being exported
"""
export_list = {}
for entry in changes:
src = ''.join(['svn://localhost/', entry])
dest = get_expanded_path(entry, root=path)
export_list[src] = dest

for src in export_list:
dest = export_list[src]
prepare_dir(dest)
SVN_CLIENT.export(src, dest)

def get_checkstyle_report(path):
""" Returns checkstyle report as a dictionary which contains amount
of checkstyle violations for every file
Args:
path - path to the checkstyle report
Returns:
dictionary which contains amount of checkstyle violations for every file
"""
report = {}
xmldoc = minidom.parse(path)
file_tags = xmldoc.getElementsByTagName('file')
for tag in file_tags:
key = tag.getAttribute('name')
value = len(tag.getElementsByTagName('error'))
if key in report:
report[key] += value
else:
report[key] = value

return report

def main (repos, txn):
""" Hook entry point """

log_dir = os.path.join(CURRENT_DIR, 'log')
if not os.path.exists(log_dir):
os.mkdir(os.path.join(CURRENT_DIR, 'log'))

# adding file handler to logger
log_path = os.path.join(log_dir, '%s_pre_commit.log' % txn)
file_handler = logging.FileHandler(log_path, mode='w')
file_handler.setFormatter(FORMATTER)
LOGGER.addHandler(file_handler)

# magic keyword which allows to skip checkstyle
checkstyle_pattern = '.*skipcheckstyle.*'
# directory which should contain files to be checked
check_dir = os.path.join(CURRENT_DIR, 'src', txn)
# path to the checkstyle report
errors_report_path = os.path.join(log_dir, \
'%s_checkstyle_errors.xml' % txn)
# maximum capacity of errors in report
max_error_cnt = 25

trans = pysvn.Transaction(repos, txn)

# checking the value of 'skip.checkstyle' option (set in the commit log)
log_msg = trans.revpropget('svn:log')
if re.search(checkstyle_pattern, log_msg):
LOGGER.info('skipping checkstyle')
sys.exit(0)

changes = trans.changed()
all_changes = []
modified = []

for path in changes:
if path.endswith('.java'):
status = changes.get(path)[0]
if status is not 'D':
all_changes.append(path)
if status is 'R':
modified.append(path)

if all_changes:

# preparing check dir
if not os.path.exists(check_dir):
os.makedirs(check_dir)
else:
clean_dir(check_dir)

# recieving contents of the files
for path in all_changes:
file_path = get_expanded_path(path, root=check_dir)
prepare_dir(file_path)
fobj = file(file_path, 'w')
fobj.write(trans.cat(path))
fobj.close()

#LOGGER.info('Executing checkstyle over committed files ...')
run_checkstyle(check_dir, errors_report_path)

cur_report = get_checkstyle_report(errors_report_path)
clean_dir(check_dir)

export_repos_files(modified, check_dir)
#LOGGER.info('Executing checkstyle over repository versions of commited files ...')
run_checkstyle(check_dir, errors_report_path)
prev_report = get_checkstyle_report(errors_report_path)

errors = []
cur_errors = 0
msg_pattern = 'The checkstyle violations amount in file \'%s\' has increased from %s to %s'
for path in cur_report:
if len(errors) < max_error_cnt:

cur_errors = cur_report[path]
if path not in prev_report and cur_errors:
errors.append((msg_pattern % (path[len(check_dir):], \
'0', cur_errors)))

elif prev_report[path] < cur_errors:
errors.append((msg_pattern % (path[len(check_dir):], \
prev_report[path], cur_errors)))
else:
pass

os.unlink(errors_report_path)
shutil.rmtree(check_dir, True)

if errors:
LOGGER.error('\nAmount of checkstyle violations has been increased:\n')
for err in errors:
LOGGER.error(err)

return 1

if __name__ == '__main__':
if len(sys.argv) < 3:
sys.stdout.write("\nUsage: %s REPOS TXN\n" % (sys.argv[0]))
else:
sys.exit(main(sys.argv[1], sys.argv[2]))
Кодстайл по максимуму поправил, длину строки до 100 символов субъективно считаю допустимой и наиболее комфортной. :)

Кажется, работает как надо. Всем, и в частности Ed'y, очень благодарен за помощь.



Отредактировано (Авг. 7, 2009 15:34:38)

Офлайн

#7 Авг. 7, 2009 13:28:04

sober
От:
Зарегистрирован: 2009-07-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

Eсли кому-то понадобится этот хук, вот build.xml, который используется для запуска чекстайла:

<?xml version="1.0" encoding="windows-1251"?>
<project name="checkstyle-checks" default="checkstyle" basedir=".">

<property name="checkstyle.home" location="checkstyle"/>
<property name="checkstyle.ruleset" value="${checkstyle.home}/checkstyle.xml"/>
<property name="checkstyle.errors" value="${checkstyle.home}/checkstyle_errors.xml"/>
<property name="checkstyle.properties" value="${checkstyle.home}/checkstyle_properties.xml"/>
<property name="check.dir" value="src"/>
<property name="log.path" value="${basedir}/checkstyle/checkstyle_errors.xml"/>

<path id="checkstyle.jars">
<fileset dir="${checkstyle.home}" includes="**/*.jar"/>
</path>

<taskdef resource="checkstyletask.properties" classpathref="checkstyle.jars"/>

<target name="checkstyle" unless="skip.checkstyle">
<checkstyle config="${checkstyle.ruleset}" failonviolation="false" maxWarnings="2147483647" maxErrors="0" failureproperty="checkstyle.failed">
<classpath>
<path refid="checkstyle.jars"/>
</classpath>
<fileset dir="${check.dir}" includes="**/*.java" excludes="**/org/apache/**/*.java">
<exclude name="**/**/antlr/*.java"/>
</fileset>
<formatter type="xml" toFile="${log.path}"/>
</checkstyle>
<condition property="checkstyle.passed">
<not>
<isset property="checkstyle.failed"/>
</not>
</condition>
</target>

</project>
Cкрипт должен лежать в папке ‘hooks’ вашего репозитория, там же должна быть директория ‘checkstyle’, содержащая джарники чекстайла и его конфигурационные файлы; в системе должны быть установлены и указаны в $PATH Java и http://ant.apache.org Те, кто считаeт, что такой велосипед неоправданно тяжелый, могут обратить свое внимание на проект http://pychecker.sourceforge.net/. :)



Отредактировано (Авг. 7, 2009 17:49:20)

Офлайн

#8 Авг. 9, 2009 16:20:32

Ed
От:
Зарегистрирован: 2008-12-13
Сообщения: 1032
Репутация: +  13  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

Ну, теперь все гораздо лучше выглядит, учитывая ваш небольшой опыт работы с Питоном.

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

--- pc_hook2.py.orig    2009-08-09 15:55:42.000000000 +0300
+++ pc_hook2.py 2009-08-09 16:13:51.000000000 +0300
@@ -16,33 +16,25 @@
import subprocess as subp
from xml.dom import minidom

-# directory in which this script is located
-CURRENT_DIR = os.path.dirname(os.path.realpath(__file__))
-SVN_CLIENT = pysvn.Client()
-
-# setup LOGGER
-LOGGER = logging.getLogger(__name__)
-FORMATTER = logging.Formatter('%(asctime)s - %(filename)s - %(levelname)s - %(message)s')
-
-
-LOGGER.addHandler(logging.StreamHandler())
+LOG_FORMAT = '%(asctime)s - %(filename)s - %(levelname)s - %(message)s'

def prepare_dir(filename):
- """ Creates directory tree if not exists """
+ """Create directory tree if doesn't exist."""
dir_path = os.path.dirname(filename)
if not os.path.exists(dir_path):
os.makedirs(dir_path)

def clean_dir(path):
- """ Removes all content of the specified directory """
+ """Remove all content of the specified directory."""
if os.path.exists(path):
shutil.rmtree(path, True)
os.makedirs(path)
else:
- raise OSError('The system cannot find the file specified: \'%s\'' % path)
+ raise OSError(\
+ 'The system cannot find the file specified: \'%s\'' % path)

def get_expanded_path(path, root=None):
- """Returns expanded, local, native filesystem working copy path.
+ """Return expanded, local, native filesystem working copy path.

Args:
path: path to expand and convert to local filesystem directory separators
@@ -54,23 +46,23 @@

return path

-def run_checkstyle(path, log_path):
- """ Executes checkstyle validation as the separate process
- which executes the Ant checkstyle task
+def run_checkstyle(path, log_path, current_dir):
+ """Execute checkstyle validation as a separate process
+ which executes the Ant checkstyle task

- Args:
- path - path that should be checked
+ Args:
+ path - path that should be checked
"""
cmd = 'ant -Dcheck.dir=%s -Dlog.path=%s' % (path, log_path)
proc = subp.Popen(cmd, shell = True, stdout = subp.PIPE, \
- stderr = subp.STDOUT, cwd=CURRENT_DIR)
+ stderr = subp.STDOUT, cwd=current_dir)
proc.communicate()

-def export_repos_files(changes, path):
- """ Exports committed files from transaction to the specified path
- Args:
- changes - list of changed files
- path - root destination of the files being exported
+def export_repos_files(changes, path, svn_client):
+ """Export committed files from transaction to the specified path
+ Args:
+ changes - list of changed files
+ path - root destination of the files being exported
"""
export_list = {}
for entry in changes:
@@ -78,14 +70,13 @@
dest = get_expanded_path(entry, root=path)
export_list[src] = dest

- for src in export_list:
- dest = export_list[src]
+ for src, dest in export_list.iteritems():
prepare_dir(dest)
- SVN_CLIENT.export(src, dest)
+ svn_client.export(src, dest)

def get_checkstyle_report(path):
- """ Returns checkstyle report as a dictionary which contains amount
- of checkstyle violations for every file
+ """Return checkstyle report as a dictionary which contains amount
+ of checkstyle violations for every file
Args:
path - path to the checkstyle report
Returns:
@@ -105,22 +96,28 @@
return report

def main (repos, txn):
- """ Hook entry point """
+ """Hook entry point."""

- log_dir = os.path.join(CURRENT_DIR, 'log')
+ current_dir = os.path.dirname(os.path.realpath(__file__))
+
+ log_dir = os.path.join(current_dir, 'log')
if not os.path.exists(log_dir):
- os.mkdir(os.path.join(CURRENT_DIR, 'log'))
+ os.mkdir(os.path.join(current_dir, 'log'))
+
+ # setup logger
+ logger = logging.getLogger(__name__)
+ logger.addHandler(logging.StreamHandler())

# adding file handler to logger
log_path = os.path.join(log_dir, '%s_pre_commit.log' % txn)
file_handler = logging.FileHandler(log_path, mode='w')
- file_handler.setFormatter(FORMATTER)
- LOGGER.addHandler(file_handler)
+ file_handler.setFormatter(logging.Formatter(LOG_FORMAT))
+ logger.addHandler(file_handler)

# magic keyword which allows to skip checkstyle
checkstyle_pattern = '.*skipcheckstyle.*'
# directory which should contain files to be checked
- check_dir = os.path.join(CURRENT_DIR, 'src', txn)
+ check_dir = os.path.join(current_dir, 'src', txn)
# path to the checkstyle report
errors_report_path = os.path.join(log_dir, \
'%s_checkstyle_errors.xml' % txn)
@@ -132,7 +129,7 @@
# checking the value of 'skip.checkstyle' option (set in the commit log)
log_msg = trans.revpropget('svn:log')
if re.search(checkstyle_pattern, log_msg):
- LOGGER.info('skipping checkstyle')
+ logger.info('skipping checkstyle')
sys.exit(0)

changes = trans.changed()
@@ -163,15 +160,15 @@
fobj.write(trans.cat(path))
fobj.close()

- #LOGGER.info('Executing checkstyle over committed files ...')
- run_checkstyle(check_dir, errors_report_path)
+ #logger.info('Executing checkstyle over committed files ...')
+ run_checkstyle(check_dir, errors_report_path, current_dir)

cur_report = get_checkstyle_report(errors_report_path)
clean_dir(check_dir)

- export_repos_files(modified, check_dir)
- #LOGGER.info('Executing checkstyle over repository versions of commited files ...')
- run_checkstyle(check_dir, errors_report_path)
+ export_repos_files(modified, check_dir, pysvn.Client())
+ #logger.info('Executing checkstyle over repository versions of commited files ...')
+ run_checkstyle(check_dir, errors_report_path, current_dir)
prev_report = get_checkstyle_report(errors_report_path)

errors = []
@@ -195,9 +192,9 @@
shutil.rmtree(check_dir, True)

if errors:
- LOGGER.error('\nAmount of checkstyle violations has been increased:\n')
+ logger.error('\nAmount of checkstyle violations has been increased:\n')
for err in errors:
- LOGGER.error(err)
+ logger.error(err)

return 1



Отредактировано (Авг. 9, 2009 16:21:07)

Офлайн

#9 Сен. 1, 2009 16:31:25

sober
От:
Зарегистрирован: 2009-07-17
Сообщения: 17
Репутация: +  0  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

Большое спасибо за патч. Применил :)

Нашел в скрипте странный баг:

for path in all_changes:
file_path = get_expanded_path(path, root=check_dir)
prepare_dir(file_path)
fobj = file(file_path, 'w')
fobj.write(trans.cat(path))
fobj.close()
В этом блоке читается содержимое файлов, которые находятся в транзакции, и записывается во временные файлы. Проблема в том, что содержимое пишется в файл с лишним переносом строки после каждой строки. Т.е. ‘\r\n’ пишется в файл как ‘\r\n\r\n’. Содержимое оригинальных файлов проверял. Кто-нибудь может объяснить природу этого явления?



Офлайн

#10 Сен. 1, 2009 16:39:46

o7412369815963
От:
Зарегистрирован: 2009-06-17
Сообщения: 1986
Репутация: +  32  -
Профиль   Отправить e-mail  

pysvn pre-commit hook

sober
fobj = file(file_path, ‘w’)
попробуй вместо флага ‘w’ поставить ‘wb’

Офлайн

Board footer

Модераторировать

Powered by DjangoBB

Lo-Fi Version