четверг, 29 июля 2010 г.

Альфы… Беты… Релизы…

Лето, июль. В белокаменной жара несусветная – ночью под тридцать, днем вообще к сорока подваливает! Мозги закипают и не распишешься даже. Разве что код. В нем хотя бы можно оставаться сестрой таланта. А посему выложу что-нибудь из давно написанного в стол. Сегодня о конфигурации бета-версий и финальных релизов. А именно, как свести выбор той или иной конфигурации к одной единственной строчке кода.

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

К примеру, в моей Aml Pages есть автоматическая проверка новых версий на сайте. Есть настройка как часто проверять, а еще есть настройка проверять только stable-версии или также проверять и наличие новых бета-версий. По умолчанию в финальной версии проверка бета-версий отключена, да и интервал автоматической проверки пореже. Совсем другое дело бета-версии. На сайте они обновляются почти каждый день, поэтому “есть смысел” включить проверку бета-версий, да и почаще проверять.

К чему всё это? А вот к чему: что же теперь делать? Менять значения настроек по умолчанию для бет и финальных версий да еще и ручками? Ну уж нет! Не хватало только перед релизом еще и в коде ковыряться (“солнце всходит, и ничего не трогай” ©). Давайте-ка эту рутину переложим на компилятор.

Прием прост как пилорама. Заводим в stdafx.h (precompiled header) два банальных макроса AP_BETA и AP_IS_BETA.

#define AP_BETA TEXT("Beta") /*это макрос для бета-версий*/
//#define AP_BETA TEXT("")     /*это макрос для финальных версий*/
#define AP_IS_BETA (_tcslen(AP_BETA)>0)  /*определить бета-версия или финал*/
Юзаем так. В коде, где нам нужно разное поведение для бет и финалов пишем нечто вроде:
if (AP_IS_BETA()) {
    //...код для бета-версий
}
else {
   //...код для финальных версий
}
Поясню мысли.
  1. Перед выпуском финального релиза крайне нежелательно лезть в дебри кода, и изменять какие-то конкретные строчки. Ошибиться можно запросто, и не заметим даже. Весело, не правда ли!?! Последняя бета стабильна, а релиз вот с багой. И все потому, что меняли какие-то мелочи да в разрозненных дебрях кода. Куда как проще поменять одну строчку в stdafx.h.
  2. Изменение precompiled header (stdafx.h) приведет к полной пересборке кода. Имхо, полная пересборка не лишнее дело перед выпуском финала.
  3. Нафига все эти определения “Beta” или же пустая строка? А когда строка не пустая, то указанный префикс “Beta” также можно автоматом куда-нибудь добавлять (окно “о программе”, заголовок окна и.т.д.). Причем если изменить само определение, ну скажем с “Beta” на “Beta 2”, код этих “добавок” менять и вовсе не придется. Только пересобрать приложение.

Собственно, на этом всё. Конечно, недостатки есть. Макрос развернется в код, отрабатывающий во время выполнения (run-time). Поэтому налево-направо может и не стоит применять этот подход. Но в моем случае было иначе: а) применение этих макросов было очень ограниченным, один раз за запуск, поэтому не накладно; б) эти  префиксы “Beta”, “Beta 2” были нужны, чтобы прописывать их в UI – так что все равно от них никуда не деться.

Не спорю, все то же самое можно свести и к времени компиляции (design-time) через те же самые шаблоны. Но как-то руки до этого и не дошли. В конце концов, мне Алесандреску шашечки надо, или ехать!?! Зато одно-единственное изменение в одной строчке, и новая конфигурация кода готова к сборке, причем безо всяких чреватых последствиями изменений где-то в недрах.

PS: как-то писал о бесплатности бета-версий. Стоит или не стоит?!? Дык вот описанный выше прием и в этом случае работает. Эксперименты ведутся. Об результатах отпишусь позже, пока еще рано о чем-то говорить (лето все таки, йоптыть – всем жарко: то ли юзера не видят полнейшей фривары в бетах, то ли я в толк не возьму, где последствия?).