Про Одну Кнопку

Страшное слово — теневой каталог. Первая ассоциация — «Призрак, летящий на крыльях ночи». Ничего, привыкнете. Хорошая сторона теневого каталога (Shadow Folder), в отличии от рабочего Каталога (Working Folder) та, что рабочих каталогов много, а теневой каталог ровно один. Поэтому его очень легко задать. Единственная маленькая трудность — его задают не с помощью программы работы с базой (Microsoft Visual SourceSafe Explorer), а вызывая программу администрирования базы — (Microsoft Visual SourceSafe Administrator/ Это естественно, ведь в базу каждый пользователь заходит от себя лично, а теневой каталог — предмет глобальный, один на всех Итак, вызываем программу администрирования, вводим пароль (логин не нужен, он всегда один — Admin) и вызываем вот такое меню:

Далее вызываем пункт меню «Options,,,», в появившейся форме выбираем закладку «Shadow Folders». В верхней строчке нажимаем кнопку «Browse», выбираем там нашу базу, и только её, в этом месте думать категорически не надо. Во второй строке вводим руками или выбираем каталог, в котором будет размещён наш Теневой Каталог. Я предпочитаю создать его заранее и на этом этапе просто выбрать.

Потом нажимаем кнопку «ОК». Если база реальная и большая, то реакция будет ощутимо медленной. Для нашей игрушечной базы всё будет исполнено мгновенно.

Что мы получим в результате? Самый простой путь узнать это — пойти и посмотреть, не изнутри VSS конечно, а из какой-нибудь внешней независимой программы. Слабые духом используют Explorer, правильные пацаны — FAR, те, кто не определились — какой-нибудь Total Commander. В выбранном каталоге мы увидим структуру каталогов, в точности соответствующую структуре проектов базы. Внутри каталогов лежат файлы, имена которых совпадают с именами файлов, которые мы видим обращаясь к базе. Ещё лежит какой-то псевдоневи- димый служебный файл, но мы его игнорируем.

А в чём преимущество, для чего мы всё это делали?

Прежде чем ответить, нам потребуется прояснить несколько технических деталей. Как хранятся в базе текстовые файлы? Текстовые файлы это не те файлы, которые содержат внутри себя текст. Файлы с расширениями DOC, DJVU и PDF текстовыми ни разу не являются. Текстовые файлы — это то, что называется Plain Textio Они содержат только коды символов и пару-тройку управляющих кодов, причем коды символов традиционные, однобайтовые, а не модный UNICODE. Но это неважно, важно то, что к текстовым файлам относятся исходные тексты программ.

А как хранятся эти файлы в базе? Мы можем посмотреть различия между последней, 225-й версией файла и версией, к примеру, 17-й. Отсюда закрадывается подозрение, что в базе хранятся все версии файлов, от первой до двести двадцать пятой. Это действительно так, но хранятся они очень специальным образом.

Первая версия хранится целиком. А для всех последующих в хитром виде содержатся только внесённые изменения. По нынешним временам выглядит это довольно глупо, проще и надёжнее было бы хранить просто все версии файлов, как они есть. Но напоминаю, даже последняя версия VSS вышла в мохнатом 2006-м году. А про первую даже и вспомнить трудно. Тогда идея хранить кучу почти одинаковых файлов на маленьком жёстком диске (40 мегабайт) казалась нелепой и кощунственной. Но, что выросло, то и выросло.

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

Теневой каталог оставляет от всего богатства, хранящегося в базе, со всем его неисчислимым количеством версий файлов только последние их версии. Структура его каталогов в точности совпадает со структурой проектов базы, но теперь мы видим простые и понятные имена файлов — именно те, которые мы туда и клали, и именно в том формате, в котором мы их туда и клали. То, что мы можем пойти и посмотреть, что же у нас в базе лежит, не пользуясь средствами базы — это, разумеется, преимущество, но небольшое. Это преимущество только для тех, кто в надёжности VSS как-то немного сомневается и хочет пощупать файлы руками.

Главное, что теперь мы можем весь наш проект изготовить то, что называется одной кнопкой, точнее нажатием этой самоц одной кнопки. Чтобы наглядно показать, как это делается, надо немного усложнить ситуацию. Сейчас наш виртуальный Василий Иванович живёт в полной гармонии с самим собою — то есть, пользуется только своими файлами. Сделаем ситуацию более сложной, такой, как мы и обещали сделать её с самого начала — В. в своей программе вызывает процедуры (функции), реализованные в модулях от А. и П. Пример будет игрушечным и простым, само собой.

Кроме того, чтобы не отвлекаться позже, отработаем несложную манипуляцию с базой. А, возможно, и познакомимся с новым понятием — консольное приложение. В каком смысле — новом?

  • «Попутная песня». Исполняется впервые.
  • Да какое впервые, её сто пятьдесят лет поют!
  • Мною — впервые.

© Винокур

То есть, это не я впервые пишу консольное приложение, а кто-то из вас, возможно, впервые о нём услышит. И увидит. Впервые.

На каком языке сейчас написана Васина программа? Можно сказать, что на псевдокоде, а можно сказать проще — на (Турбо) Паскале. На Турбо Паскале, к сожалению, уже не программируют, поэтому меняем всё, ничего по существу не меняя. Переносим программу из Турбо Паскаля под Delphi, но делаем её консольным приложением.

Быстро отвечаю на несколько несложных незаданных вопросов.

Что такое консольное приложение? Это такая программа как под DOS, но под Windows. Не поняли? Сейчас поймёте.

Откуда они берутся, консольные приложения? Можно написать его полностью руками, например в «Блокноте», и сохранить с расширением DPR, а можно в меню выбрать FileNew Other и на первой же закладке выбрать Console Application. Получите заготовку маленького проекта.

Зачем нужны консольные приложения? Не знаю. Я за последние пятнадцать лет написал ровно три штуки — они молча чистили каталоги от ненужных файлов. Можно было бы сделать их обычными приложениями Delphi, но мне так было проще — после привычной работы с Турбо Паскалем. А вообще, по-моему, единственное назначение консольных приложений — гордиться, что вы умеете их писать.

Итак, очередная (пока ещё промежуточная) версия Васиной программы теперь выглядит вот так.

program progOne;

{$APPTYPE CONSOLE}

uses

ankaGrafl, petiaFormulal;

var

R : single;

V : single;

begin

R: =10;

V: = (4/3) * 3.1415 * R*R*R;

Writeln( 'V = 4:1:2);

Readln;

end.

Вторым номером идет волшебная строка, которая. Собственно, и делает приложение консольным. В остальном, это один в один паскалевская программа. Чем дольше живёшь, тем больше видишь, что ничего, в сущности, не меняется.

А что будет, если мы программу в её нынешнем состоянии запустим на выполнение? Получим мы вот такое жутковатое зрелище:

Так вот ты какое, консольное приложение! Очень похоже на древний заплесневелый MS DOS.

Возвращаемся к Петьке и Анке, они уже подключены, но ещё не реализованы. То есть, что-то там формально под этими именами в базе лежит, но немножечко пустое. Надо срочно реализовать.

Теперь несложная операция с базой. Мы помещаем (добавляем/Add) наш, только что созданный, файл в базу. Операцию Check Out мы при этом не делаем. Почему? Потому, что наш старый фал имел расширение PAS (был паскалевской программой). Наш новый файл имеет расширение DPR (является проектом Delphi). Друг друга они заменяют, но не замещают. Мы не меняем одну версию файла на другую версию того же файла, мы меняем один файл на другой. Поэтому, положив новый файл в базу, мы удаляем старый. Можно и не удалять, но когда вы засорите проекты ненужными старыми файлами, в которых невозможно разобраться, вы об этом пожалеете.

При попытке удалить файл, мы получим вот такой запрос:

Смысл вопроса в том, хотим ли мы наш файл Delete (с возможностью восстановления) или Destroy {бритвой по горлу и в колодец — © Джентльмены удачи). На этой мелочи можно было бы и не останавливаться, но дело в том, что две эти операции требуют разных прав доступа к VSS. Сейчас это не важно, потом разберётесь, вместе с администратором базы.

А модули Петьки и Анки реализованы следующим образом:

Первый модуль от Анки:

unit ankaGrafl; interface

{-----------------------------------------------------------------

}

procedure ShowV( R,V : single);

{-----------------------------------------------------------------

}

implementation

uses

SysUtils;

{-----------------------------------------------------------------

}

procedure ShowV( R,V : single);

begin

Writeln( 'Volume of sphere with radius ' + FloatToStr(R) +

' is equal ' + FloatToStr(V));

end;

{-----------------------------------------------------------------

}

end.

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

unit petiaFormulal; interface

{----------------------------------------------------------}

function VolumeOfSphere( R : single) : single;

function AreaOfCircle( R : single) : single;

{----------------------------------------------------------}

implementation

{----------------------------------------------------------}

function VolumeOfSphere( R : single) : single;

begin

result:=(4/3) * pi * R*R*R;

end;

{----------------------------------------------------------}

function AreaOfCircle( R : single) : single;

begin

result:=pi * R*R;

end;

{----------------------------------------------------------}

end.

Здесь у нас целых две функции, для объёма шара и площади круга. Пользователи Дельфи могут бросить мимолётный взгляд на идентификатор PI и задуматься, почему он нигде не объявлен и за что к нему такое уважение (он объявлен в модуле System, который подключается автоматически).

Но в целом всё понятно, в смысле понятно, какие функции эти модули реализуют.

Соответственно, корректируется и головная программа от Васи. Теперь Вася не занимается чёрной работой по формулированию формул и выводом вывода — теперь Вася только даёт команды Петьке и Анке.

program progOne;

{$APPTYPE CONSOLE}

uses

ankaGrafl, petiaFormulal;

var

R : single;

V : single;

begin

R: = 10;

V:=VolumeOfSphere (R);

ShowV(R,V);

Readln;

end.

Наша технология изготовления Программного Продукта будет оформлена как файл типа ВАТ, называемый также «пакетный файл». Можно сделать и по другому, это всегда можно, но книга имеет конечный объём. К сожалению, только написав эти слова, я задумался — а вы знаете, что такое файл типа ВАТ? Сейчас это называется скриптовый язык. Как говорили в моём детстве — «Кулер тоже вертолёт, только маленький ещё». То есть, файл типа ВАТ действительно является скриптовым языком, только очень примитивным. Настолько примитивным, что вы в нём легко интуитивно разберётесь. Напомним структуру теневого каталога нашей базы.

Base-Shadow

AllCommon

Anka

Bat

Petia

Vasia

Проект (каталог) Bat только что появился — в нём будет храниться то, что нужно нам для изготовления Программного Продукта одной кнопкой. Проекты Anka и Petia, строго говоря, нас вообще не интересуют — их содержимое дублировано в проекте AllCommon, точнее, не всё содержимое, а то, что представляет интерес для внешнего мира. Проект, в смысле Delphi, который мы транслируем, находится в проекте, в смысле VSS, с именем Vasia.

Здесь я не буду по шагам излагать ход мысли, который привёл меня к этому результату, а сразу покажу результат и его прокомментирую. Итак, в нашем не очень сложном случае в проекте Bat будут два файла, с вот такими именами и вот таким содержанием:

makeProgOne.bat els

сору/у dcc32_progOne.cfg c:delphi7indcc32.cfg

rmdir /s /q e:progOne

mkdir e:progOne

cd e:Base-ShadowVasiaprogOne

call progOne e:Base-Shadow

rem the end ----------------------------------------------

dcc32_progOne.cfg

  • -aWinTypes=Windows;WinProcs=Windows;
  • -uc:delphi7lib -ее:progOne -luVcl;
  • —$0—
  • — $D—
  • —$L—
  • -$J+

Первый файл выглядит более пристойно со смысловой и эстетической точки зрения, что и немудрено — это его надо запустить, чтобы изготовить Программный Продукт. Файлы с расширением ВАТ запускаются также легко и непринуждённо, как и файлы с расширением EXE. Полужирным шрифтом выделено то, что официально называется «внутренняя или внешняя команда». Далее построчный разбор шедевра.

els

Всего-навсего очистка экрана, если мы запускаем ВАТ-файл, к примеру, из- под FAR. Необходимо на этапе отладки, потом несущественно.

сору/у dcc32_progOne.cfg c:delphi7indcc32.cfg

Как легко догадаться, имеет какое-то отношение к нашему второму файлу, вместе с ним обсудим и эту команду.

rmdir /s /q e:progOne mkdir e:progOne

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

cd e:Base-ShadowVasiaprogOne

Переходим в каталог (проект), где лежит файл проекта (DPR) самой главной Васиной программы.

call progOne е:Base-Shadow

Запускаем ещё один, специфически Васин, ВАТ-файл. О нём позже, главное, что в его задачу входит изготовление Васиной программы. Почему нельзя было обойтись одним пакетным файлом? Потому что Программный Продукт часто состоит не из одного исполняемого файла и/или динамической библиотеки. Чаще их много. В этом случае пакетный файл верхнего уровня будет по-прежнему один, хотя и более сложной структуры, а пакетных файлов второго уровня прибавится в количестве.

rem the end ----------------------------------------------

А это, как легко догадаться, просто комментарий.

Теперь займёмся вторым файлом, он имеет расширение CFG и совсем не исполняемый. Расширение это очень любят все разработчики, поэтому, что скрывается внутри, определить заранее невозможно. В нашем случае это конфигурационный файл проекта Delphi. Файлов таких на компьютере может одновременно существовать очень много, поэтому есть определённые правила, какой именно из них применять в данном конкретном случае. В тонкостях вы разберётесь сами, а пока о главном. При создании проекта в среде Delphi конфигурационный файл обычно автоматически создаётся в каталоге проекта, он же, естественно, и применяется.

Мы конфигурационный файл в базу не кладём, поэтому, как можно догадаться, его там и нет. Вместо этого мы помещаем наш конфигурационный файл в Самый Главный Каталог Delphi, заменяя нашим файлом тот файл, который используется по умолчанию. Обратите внимание, старый файл мы не запоминаем в начале и не восстанавливаем в конце. А зачем? Этот файл нужен только тогда, когда нет конфигурационного файла в каталоге проекта, а он есть всегда, когда мы работаем в IDE Delphi — вы ведь знаете, что это такое? Теперь построчный разбор.

  • -aWinTypes=Windows;WinProcs=Windows;
  • -uc:delphi7lib

Так положено. Если Delphi установлен в другом каталоге, поправьте вторую строку. Обратите внимание на отвратительный синтаксис uc:delphi7. Поубивал бы.

-ее:progOne

А это мы назначаем, в какой именно каталог отправятся наши оттранслированные файлы. Если вы не догадались сразу — e:progOne.

-luVcl;

Какие мы используем пакеты (packages). В данном случае только Vcl.bpl.

Далее опции компилятора, с этим вы легко разберётесь.

Третий, и последний командный (пакетный) файл. Если вы не забыли, мы переходим в главный Васин каталог и вызываем его личный пакетный файл, вот такого содержания:

dcc32.exe /U%lallCommon progOne.dpr

Выглядит ужасно, а содержание очень незатейливо. Мы вызываем программу (dcc32.exe) и передаём ей на вход два параметра, разделённых пробелами. Сама программа представляет собой компилятор командной строки Delphi, то есть мы транслируем программу не из среды Delphi, а почти молча. Маленькая особенность — для всех версий Delphi я не проверял, но будет лучше, если в момент исполнения этого файла среда Delphi НЕ будет загружена. Второй параметр очевиден — это та программа, которую мы должны транслировать. Первый параметр чуть сложнее.

% — это то, что называется формальный параметр. Фактический параметр, в нашем случае — e:Base-Shadow, то есть местонахождение нашего теневого каталога. К нему приклеивается продолжение — allCommon. В сочетании с волшебным ключом /U получаем адрес, по которому надо искать необходимые для трансляции модули. Обдумайте.

 
Посмотреть оригинал
< Пред   СОДЕРЖАНИЕ   ОРИГИНАЛ     След >