31 августа 2007 г.

Расширяем возможности cleartool, ч. 2

Кроме отсутствия в cleartool команды status, мне совершенно не нравится семантика команды cleartool diff. Действительно, после простой и удобной команды svn diff file.c, предназначенной для просмотра локальных изменений в файле file.c, строка cleartool diff -pre -dif file.c кажется слишком неудобной. И что самое главное — командой cleartool diff нельзя просмотреть изменения в нескольких файлах одновременно.

Но у меня есть волшебный скрипт, который неожиданно оказался вполне расширяемым :)

Итак, мне нужна простая команда diff, которая мне покажет локальные изменения для одного или нескольких файлов. Назовем ее sdiff и добавим в парсер аргументов скрипта:

case "$1" in
  sdiff) shift; sdiff $*;;
  status) shift; status $*;;
  *) $CT $*;;
esac

Теперь нужно создать функцию sdiff(), которая бы выводила изменения для всех переданных в командной строке имен файлов:

sdiff()
{
  if [ 0 = $# ]; then
    echo "ERROR: at least one argument should be passed."
    exit 1
  fi

  for T in $*; do
    echo "Index: $T"
    echo "---------------------------------------------"
    $CT diff -dif -pre $T
    echo
  done
}

Ну, вот и все. Синтаксис новой команды такой:

ct sdiff pname [pname ...]

где pname — имя файла или директории.

29 августа 2007 г.

Адское программирование

С языком программирования Ada мне удалось связать свою программистскую жизнь всего на несколько лет. Но даже их хватило, чтобы понять — использование этого языка позволяет программисту заниматься программированием, а не круглосуточной ловлей багов в своих собственных программах. До моего знакомства с этим языком, я скептически относился к таким утверждениям, но весь мой скепсис улетучился, когда после нескольких месяцев работы я понял, что ни разу не воспользовался отладчиком. Ада меняет образ мышления программиста, причем, в лучшую сторону. Возможно, это звучит излишне пафосно, но это действительно так.

Сейчас, вернувшись к C и C++, я часто ловлю себя на мысли, что мне очень недостает адских возможностей. Но, как оказалось, по этому языку скучаю не я один :) Ричард Херрик так соскучился по возможностям языка Ада, что решил создать свою собственную реализацию адских ограниченных типов данных на C++, которую и предлагает нашему вниманию. И на мой взгляд, вполне достойную реализацию. К сожалению, пока речь идет только о целочисленных типах, но лиха беда начало :)

Читать статью "Ada-style Ranged Types in C++"

10 августа 2007 г.

Расширяем возможности cleartool

Так получилось, что по воле объективных причин недавно пришлось сменить систему контроля версий. До этого я использовал Subversion, и, надо признаться, с удовольствием использовал. Еще раньше был CVS, но, мне кажется, это все-таки прошлый век, и Subversion мне нравится гораздо больше. Однако, проблема Subversion в том, что в больших проектах его очень трудно использовать. Частично из-за его ограниченной производительности, частично из-за отсутствия средств автоматизации и интеграции с другими продуктами. И вот, пришлось пересесть за ClearCase, этого необъятного монстра. Говорят, много в нем хорошего, но и плохого — тоже немало. Точнее, не плохого, а неудобного. Хотя, возможно, это просто с непривычки...

В Subversion есть замечательная команда status, которая показывает все локальные изменения, произведенные с репозиторием. И хотя возможности этой команды достаточно широки, в подавляющем большинстве случаев я использовал эту команду, чтобы получить список измененных мной файлов, а также добавленных или удаленных. Обычно это делалось перед занесением изменений в репозиторий. В CVS для этих целей применялась команда update.

Используя cleartool, — консольный инструмент для работы с репозиторием ClearCase, — я обнаружил, что не могу найти простого и легкого способа получить список измененных мной файлов. Возможно, я плохо искал, но перерыв man и документацию по cleartool, я не нашел команды, аналогичной svn status. (Если такая команда все же есть, буду благодарен человеку, который мне ее покажет.)

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

#!/bin/sh

CT=cleartool

show_status()
{
  for T in $*; do
    PRE=" "
    $CT diff -pre -opt "-sta" $T || PRE="M"
    echo "$PRE $T" | tr -s "//" "/"
  done
}

status()
{
  CT_LSCO="$CT lsco -s -cvi -me"
  show_status `$CT_LSCO $*`
}

case "$1" in
  status) shift; status $*;;
  *) $CT $*;;
esac

Файл скрипта я назвал ct (сокращенно от cleartool) и положил в папку $HOME/bin, которая прописана у меня в системной переменной $PATH. Таким образом, я могу вызвать мой скрипт из любой директории.

Итак, зачем это. Скрипт построен таким образом, что все аргументы, указанные при запуске скрипта, передаются команде cleartool. Таким образом, скрипт ct является неким псевдонимом команды cleartool. Например, команда

ct ls -r /vob/myproject/somelib

эквивалентна вызову

cleartool ls -r /vob/myproject/somelib

Однако, ct — это не просто псевдоним, а псевдоним с дополнительными возможностями. Вызвав команду ct status, можно получить список "вычекнутых" из репозитория папок и файлов текущим пользователем для текущего view. Файлы, которые были изменены, будут помечены буквой M, как и при выполнении svn status. Общий формат вызова ct status такой:

ct status [-r] [pname ... ]

где pname — имя папки или файла репозитория (может быть указано несколько имен). Если pname не указывать, команда будет выполнена для текущей директории. Ключ -r переводит команду в рекурсивный режим — команда status будет выполнена для всех вложенных поддиректорий.

Например, необходимо получить статус файлов и поддиректорий для папки /vob/myproject/someapp:

$> ct status -r /vob/myproject/someapp

M /vob/myproject/someapp/file.c
  /vob/myproject/someapp/file.h
M /vob/myproject/someapp/main.c
M /vob/myproject/someapp/include/types.h
  /vob/myproject/someapp/include/ext/ext.h

Результат выполнения команды показывает, что из репозитория были "вычекнуты" файлы file.c, file.h, main.c, types.h и ext.h, а изменены только file.c, main.c и types.h.

Получившийся скрипт, конечно, далеко не идеален. Но пока у меня с ним возникла только одна проблема: невозможно передать в качестве аргумента строку, состоящую из нескольких слов. Например, вот такая команда работать не будет:

ct ci -c "Some text here." file.c

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

$> ct ci file.c
Some text here.
.
<Ctrl+E>