Содержание

Проблема

При грамотном процессе разработки, с применением средств групповой работы, таких, как:

накапливается огромная история коллективного взаимодействия команды.


Хочется:

Работа
кто, как и где «вкалывает»,
Взаимодействие
кто с кем, и в каких темах
например:

Однако на практике возникает проблемы:

Question.svg как эффективно исследовать этот пласт информации?

Question.svg как эффектно показать свою работу лицом?


Question.svg Может посчитать метрики? Ненавистные SLOC и иже с ними? Да, такие инструменты есть:

В зависимости от глубины детализации можно получить:


Question.svg Читать логи переписки и коммиты в VCS? No.svg То есть разрабатывать «шахту знаний» киркой и мотыгой? Бродить по лесу и считать деревья? Муторно!


Question.svg Что же делать?

Есть альтернативный способ «увидеть лес за деревьями» и при этом выжать краткую информацию по процессу — Визуализация. В динамике!

Визуализация

Есть уже даже несколько моделей!

Целых две ☻ .

Codeswarm

Основная идея



А также:

Gource

Основная идея

Видны:

Что не хватает?

Important.svg Именно поэтому «самодельных» визуализаций — почти нет!


Наш фреймворк ShowTeamWork

Important.svg Наше решение все это делает!

А именно:

Примеры

Альбом готовых визуализаций для известных софтверных проектов ( bugzilla, bzr-svn, codeswarm, ffmpeg, freemind, git, gource, inkscape, mediawiki, mercurial, mplayer, postgres, subversion, viewvc) можно посмотреть здесь.

Мы используем

Свободные, open-source программы:

А также несколько треков свободно доступной электронной музыки от Tunguska Music Society (License: Creative Commons). Если вы поленитесь искать музыку — мы сделаем клип на базе случайного трека (несколько треков идут в комплекте). Бесплатно и патриотично! Если хотите публиковать свои ролики, напоминаем о пока еще существующих цифровых правах на музыку и рекомендуем использовать только свободно доступную музыку — тут огромный выбор музыки в стиле Ambient.

Инсталляция

Проект (исходники и бинарники) хостится на Google Code — http://code.google.com/p/showteamwork/.

То есть скомпилированные под Windows бинарники, вместе можно скачать отсюда, а если хотите поучаствовать в разработке — см. http://code.google.com/p/showteamwork/source/checkout

Единственное софтверное требование под Windows — наличие Java (все остальное идет в комплекте).

Под Linux нужно установить (из исходников или пакетами — неважно):

и сделать, чтобы эти утилиты были прописаны в путях.

Cразу посмотрите каталог samples, должно быть все понятно.

Чуть позже, мы подробно распишем здесь назначение каждой настройки.


Быстрый старт

Caution.svg Для Windows-пользователей. Linux-пользователи, думаю, поймут сами, что и как.

Скачайте дистрибутив, распакуйте куда-нибудь его. Зайдите в каталог проекта, то есть воркспейс под одной из систем контроля версий (CVS, SVN, GIT, Bazaar, Mercurial), причем не обязательно верхний уровень — можно на два-три уровня ниже, и вызовите showteamwork.exe, и отправляйтесь пить кофе.

В конце работы вы получите в каталоге, в котором его запустили пару видеофайлов (с codeswarm и gource визуализациями, по именам все будет понятно), а также вспомогательные файлы настроек и аудио, с префиксом stw-.

Далее, вы сможете редактировать эти файлы, подбирая оптимальные настройки, подходящую музыку, и редактируя историю проекта в субтитрах, и по окончании редактирования, перезапускайте showteamwork.exe.

Пересчет будет относительно экономичным — например, если вы меняли только параметры относящиеся к codeswarm-визуализации, то gource-визуализация пересчитыватся не будет, а если правили только субтитры — то будет выполнятся только наложение субтитров, без вызова gource или codeswarm.

Более детально, схема генерации описана ниже.

Схема генерации

Кликабельная (!) схема генерации:

Упрощенная схема генерации представлена выше.

Note.svg Единственное необходимое — история проекта, в виде лог-файла, файла-генератора лог-файла, или просто workspace-проекта под одно из известных VCS, у которое лог-файл можно запросить.

Будучи запущенной ShowTeamWork без дополнительных файлов автоматически проанализирует лог, и

А теперь поясним, зачем остальные сложности.

getlog.py

При отсутствии известного системе логфайла, ShowTeamWork пытается вызвать скрипт getlog.py, где вы пропишете, что и откуда надо тянуть. Например, вы собираетесь визуализировать историю большого проекта, у которого свой репозиторий, независимый от вашего проекта по его визуализации, то надо как-то прописать, как вытащить лог этого проекта.

getlog.pyPython-скрипт, он мультиплаформенный, в отличие от bat-файлов или shell-скриптов, и собственно не требует знания Python — для всех проектов в подкаталоге samples есть скрипт getlog.py, так что при необходимости, просто скопируйте скрипт, вытаскивающий лог из нужной вам системы контроля версий (в каталоге samples представлены все поддерживаемые типы VCS).

В скрипте, вы можете указать, например, параметры ограничивающие дату выборки лог-файла (например, только «последний спринт»).

import os
import datetime
 
begindate=(datetime.date.today()-datetime.timedelta(days=14)).strftime("%Y-%m-%d")
os.system(
"""
svn log  --xml --verbose --revision "{%(begindate)s}:HEAD" http://svn.wikimedia.org/svnroot/mediawiki/ >svn-log.xml
""" % vars())

Или вы можете написать свой скрипт, который, например, будет доставать данные из вики-системы, трекера-задач, системы документооборота или любой системы, подразумевающей командную работу.

После работы этого скрипта, ожидается, что в каталоге будет один из следующих файлов:

cvs.log
получаемый командой
 cvs log
svn-log.xml
получаемый командой
 svn log --xml --verbose
bzr.log
получаемый командой
 bzr log -v
git.log
получаемый командой (без шуток и одной строкой):
git log --name-status  
    --pretty=format:"%n------------------------------------------------------------------------%nr%h | %ae | %ai (%aD) | x lines%nChanged paths:
hg.log
получаемый командой
 hg -v log
activity.xml
Стандартный XML-формат представления активности (см. #activity.xml).

Если getlog.py не обнаружено, или он не выдал ожидаемые лог-файлы, ShowTeamWork пытается получить их самостоятельно, ожидая, что ее запустили в каталоге проекта под какой-нибудь системой контроля версий. ShowTeamWork смотрит, нет ли одного из следующих подкаталогов (в каталоге запуска или на один-два уровня выше) CVS, .svn, .bzr, .git, .hg — и обнаружив таковой, пытается получить лог-файл от соответствующей системы контроля версий (должна быть установлена и «в путях»).

activity.xml

Стандартный XML-формат представления активности (когда, кто, с чем, что сделал):

<?xml version="1.0"?>
<file_events>
<event 
  date="1263155767000" 
  author="rotem"
  action="A"
  filename="/trunk/phase3/languages/messages/MessagesEn.php" 
  comment="Localization update for he, and whitespace fix in en.. " />
<event 
  date="1263155767000" 
  author="rotem"
  action="M"
  filename="/trunk/phase3/languages/messages/MessagesHe.php" 
  comment="Localization update for he, and whitespace fix in en.. " />
</file_events>

Т.е. все просто — последовательность event вложенных в file_events, а атрибуты event следующие:

date
Время события в миллисекундах от стандартной компьютерной эпохи (1970…).
author
Автор действия
filename
путь
action
(необязательно)
A
добавление
M
модификация
D
удаление
comment
(необязательно) — комментарий

Кодировка — UTF-8, но если не подходит, пытается попробовать однобайтовые русскоязычные 1251/koi-8.

stw-filter-events.py

В этом файле (по умолчанию будет сгенерирована «заготовка-рыба») определяется функция filter_events, которой передается объект event, с атрибутами, описанными выше, и которая возвращает

Для чего это нужно? Например, для того, чтобы обфускировать идентификаторы авторов или наоборот, восстанавливать, сводить несколько идентификаторов вида вася@дома, <Василий Иванович Васильев> вася@office и вася@gmail к одному IDу вася. Для того, чтобы игнорировать некорректные входы (например даты из будущего — такое бывает).

Вот, к примеру фильтры для проекта bzr-svn — фильтруем события из будущего, сводим всех jelmer к одному, и для всех авторов пытаемся вытащить их email, выкинув ФИО и прочее:

def filter_events(event):
    # You can modify event attribute, or disable (filter) event, returning False
    # Sample processing below
    emailre_ = re.compile(r"(?P<email>[-a-z0-9_.]+@(?:[-a-z0-9\.]+))",
                    re.IGNORECASE)
 
    if event.date > time.time()*1000:
       return False # Something wrong: event from future
 
    if event.author.startswith("jelmer"):
       event.author="jelmer@samba.org"      
    event.author = event.author.lower().replace('"',"'")
    m = emailre_.search(event.author)
    if m:
        event.author = m.group('email') 
    event.author = event.author.replace('"',"'")
    if event.author in ["(no author)"]:
        event.author = "anonymous"
 
    event.comment = re.sub('[Bb][Uu][Gg]\s*\d+\.?', '', event.comment)
    if event.comment.startswith("*** empty log message ***"):
        event.comment = ""
 
    if len(event.comment) < 10:
        event.comment = ""
 
    return True


А также для «сведения» файловых путей (например, если CVS-репозиторий перемещался по файловой системе. Например, для вычисления истории PostgresQL, мы применяем следующий фильтр:

def filter_events(event):
    prefixes=[
        "/Users/neilc/postgres/cvs_root/",
        "/home/projects/pgsql/cvsroot/",
        "/projects/cvsroot/"
    ]
 
    for p in prefixes:
        if event.filename.startswith(p):
           event.filename=event.filename.replace(p,"/") 
    return True


stw-scenario.txt

Файл текстового «сценария» — история проекта в субтитрах. Строка начинающаяся с #, считается комментарием, остальные непустые строки состоят из даты и текста, разделенных пробелом[ами].

Дата
в формате %d.%m.%Y или %Y-%m-%d, как вам угодно.
Комментарий
простая текстовая строка в кодировке UTF-8.

По умолчанию, генерируется «заготовка-рыба» из событий, где для каждое первое появление нового участника пишется «Hi <участник>!», плюс закомментированная строка с лог-комментарием для каждого коммита — вы можете пройтись по тексту, выделить и раскомментировать ключевые события.

stw-config.py

Основной файл настроек.

Он также представляет собой скрипт на Python, в котором вы можете делать что угодно, главное — заполнить две строковых переменных

config
Собственно строка общей конфигурации, где перечислены настройки в формате «параметр=значение». Хотя большая часть настроек относиться только к Codeswarm-визуализации.

Наиболее важными будут параметры раскраски (вы наверняка захотите поменять их), ведь только автор знает, какое деление по каталогам правильно (по умолчанию, цветовая карта создается для каталогов с наибольшей активностью, что конечно, не всегда правильно). Вот некоторый пример для визуализации Bugzilla — смысл, думаю понятен (метка, регэксп, ргб-цвет):

 ColorAssign1="Attic",    "/cvsroot/mozilla/webtools/bugzilla/Attic.*",    255,242,146,  255,242,146
 ColorAssign2="Bugzilla", "/cvsroot/mozilla/webtools/bugzilla/Bugzilla.*", 207,240,62,   207,240,62
 ColorAssign3="docs",     "/cvsroot/mozilla/webtools/bugzilla/docs.*",     198,152,247,  198,152,247
 ColorAssign4="template", "/cvsroot/mozilla/webtools/bugzilla/template.*", 6,195,37,     6,195,37
 ColorAssign5="contrib",  "/cvsroot/mozilla/webtools/bugzilla/contrib.*",   132,120,49,   132,120,49
 ColorAssign6="skins",    "/cvsroot/mozilla/webtools/bugzilla/skins.*",       9,115,81,     9,115,81 

Caution.svg важно — нумеровать нужно последовательно, не пропуская цифр.

Из остальных, наиболее важных параметров, отметим следующие

Width
Ширина видео.
Height
Высота видео.
DrawNamesHalos
Рисовать гало вокруг меток (только для codeswarm).
ShowEdges
Показывать ли линии притяжения (только для codeswarm).

Для чего такие сложности? Просто генерация видео штука очень долгая, и сильно зависит от размера ролика. Поэтому, вы можете сначала сделать черновое видео маленького размера, и без спецэффектов, на котором обкатаете музыку, цвета, субтитры — и только потом, смените один символ, и сгенерируете видео высокого разрешения. Типичная часть из stw-config.py выглядит как-то так:

draft=0
if draft:
    config+="""
Width=512
Height=384
DrawNamesHalos=false
ShowEdges=false
    """
else:
    config+="""
Width=1280
Height=800
    """


engine
Выбор типа визуализации и параметров, только для Codeswarm-визуализации.

Note.svg Рекомендуем использовать только «PhysicsEngineSimple» визуализацию, как наиболее разумную (и не зависающую). Типичный набор параметров:

# name of the engine class
name=PhysicsEngineSimple
# parameters specific to this engine
edgeMultiplier=1.0
speedMultiplier=1.0
nodesMultiplier=100.0
drag=0.05

Тут наиболее интересен параметр nodesMultiplier — сила отталкивания элементов — если у вас все слишком далеко друг от друга, а лентяев вообще выкидывает к границе экрана — можете уменьшить, если все свалились в кучу — увеличивайте. За более детальными параметрами визуализации Codeswarm, обращайтесь к на страницу этого проекта.

Также в этом скрипте можно задать параметры:

GOURCE
Ненулевое значение — делать ролик с Gource-визуализацией. По умолчанию — делать.
CODESWARM
Ненулевое значение — делать ролик с CODESWARM-визуализацией. По умолчанию — делать.

В общем, см. примеры файлов stw-config.py в подкаталоге дистрибутива samples.

stw-audio.mp3

Музыкальный файл сопровождения. Если вы не предложите свой, будет взят случайный файл из подкаталога audio.

Note.svg Так что если у вас есть любимая коллекция музыки, и вы собираетесь визуализировать кучу проектов, не подбирая индивидуально звук для каждого проекта, просто залейте вашу коллекцию в подкаталог audio, оттуда mp3-файл будет выбираться случайно.

TemporaryCache

Структуру временных файлов описывать специально не будем, отметим только, что все они лежат в вашем каталоге для временных файлов (под Windows он указан в переменной TEMP), в подкаталогах с префиксом STW- (кстати, они с атрибутами скрытых файлов под Windows).

Кстати, на диске с каталогом временных файлов может потребоваться немало места — размер зависит от проекта, но в целом, порядка нескольких гигабайт на проект.

Если у вас что-то как-то пошло не так (прервали генерацию, а потом, что-то как-то не так выглядит), или просто место понадобилось — можно очистить кеш, стерев эти каталоги.

Контакты

Все баги, пожелания и предложения, пожалуйста сюда. Ну, на худой конец, обращайтесь на прямую — все мои контакты: Стас Фомин.

Резюме

Результаты полезны для:

В принципе, наверное все сказано, на всякий случай, вдруг кому пригодится — короткий доклад о ShowTeamWork на конференции AgileDays-2009 (особого ничего нового, по сравнению с написанным выше).


Проблемы и ToDo

Примечания

  1. На самом деле сейчас уже есть интересные варианты с нетривиальной статической визуализацией SVN-репозиториев: SVNPlot, примеры: [1], [2]. Но в динамике все равно гораздо веселей.
  2. Свободный, выпущенных под лицензией Creative Commons

Любые правки этой статьи будут перезаписаны при следующем сеансе репликации. Если у вас есть серьезное замечание по тексту статьи, запишите его в раздел «discussion».

Репликация: База Знаний «Заказных Информ Систем» → «ShowTeamWork»


Статья реплицируется в Wiki4IntraNet.