2013-10-07 2 views
0

Мне нужен способ перечислить все методы python, которые были затронуты между двумя наборами меркурийных изменений. Есть ли доступный инструмент, который легко это сделает?Как я могу определить методы, затронутые в HG changset?

Разъяснение на основе комментариев:

Я не ищу что-то 100% всеобъемлющей. Если инструмент может идентифицировать каждую строку, измененную в diff, то какой метод/класс она попадает внутрь, это было бы здорово.

+0

Если «влияние» включает в себя метапрограммирование как декораторы и динамически создаваемые классы (что было бы очень полезно), то это практически невозможно, за исключением, возможно, путем импорта кода. – delnan

+0

@ delnan Я понимаю, что что-то полностью всеобъемлющее слишком много, чтобы спросить. См. Редактирование на мой вопрос. – AgDude

+0

Почему не просто grep diff для класса/def? – goncalopp

ответ

0

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

Вот два возможных решения без лишних подробностей: Решение 1. Проделайте разницу между наборами изменений и убедитесь, что в вашей команде hg diff имеется много контекста (опция -U), а затем есть простой скрипт, который ищет от изменений строк до ближайшего определения функции (должно выполняться простое регулярное выражение)

Решение 2: Разберите diff как указано выше для номеров строк изменения (например, @@ -7,6 +7,10 @@) а затем напишите интроспективный инструмент, который сообщает вам, из какой функции эта строка исходит. Очевидно, что это может быть довольно сложным, но здесь очень простое приближение:

import sys 

    if __name__ == '__main__': 
     import foo 
     f_list = [] 
     in_line = int(sys.argv[1]) 
     for k,v in sys.modules['foo'].__dict__.iteritems(): 
      if k.startswith('__'): 
       continue 
      if hasattr(v, '__call__'): #We have a function 
       f_list.append((v.__name__, v.__code__.co_firstlineno)) 
     #sort our function list according to starting line of each function (if needed) 
     last_fn = None 
     for f_name, f_line in f_list: 
      if f_line >= in_line: 
       break; 
      else: 
       last_fn = f_name 

     if last_fn: 
       print 'Line {} is probably in function {}'.format(in_line, last_fn) 

Здесь я просто смотрю в модуле обув, но который может быть изменен на любой модуль вам нужно. Я не собираюсь, чтобы вставить содержимое моего модуля, так что вы должны доверять мне, что это работает :)

./intro.py 7 
    Line 7 is probably in function do_foo 

    ./intro.py 13 
    Line 13 is probably in function do_blah 
+0

Спасибо за предложение. Вариант 2 - это в основном то, что я имел в виду. Когда я получу немного больше времени, я реализую нечто подобное. – AgDude

0

Идентификация «текущего метода», очевидно, зависит от языка файла, поэтому вы не найдете готового решения в наборе mercurial. Но не слишком сложно сканировать файл python вручную и отслеживать текущий класс и метод (пока код не воспроизводит игры с синтаксисом). Вы сказали, что вам не нужно быть пуленепробиваемым, не так ли?

Если один из сопоставляемых изменений является предком другого, вы должны получить довольно хороший пробег из hg annotate (a.k.a. hg blame), в котором сообщается, когда в последний раз была затронута каждая строка в вашем файле. Затем вы можете сканировать файлы для последних изменений и в то же время отслеживать текущий класс и метод или функцию.

Если изменения имеют более сложную взаимосвязь, вам, возможно, придется выполнить определенную работу: запустите разницу между двумя версиями и проанализируйте вывод diff для списка пар строк файла, которые изменились; затем сканируйте исходные файлы, чтобы выяснить класс и метод, содержащий каждое изменение. (В качестве альтернативы вы можете предварительно обработать исходные файлы для создания индекса, , затем просмотрите различия).

Смежные вопросы