phing.tasks.ext.SvnExportRevisionDiffTask

В последнее время в посещаемых мною форумах и конференциях часто всплывает тема деплоя php-приложений на production-сервер. Я решил поделиться собственным рецептом.

В распоряжении имеется:

  1. svn-репозитарий с проектом.
  2. ftp-доступ к рабочему серверу.
  3. установленный и готовый к тяжёлой рутине phing

Сценарий работ следующий:

  1. Сделать экспорт кода из svn
  2. Подготовить его к загрузке (например убрать комментарии, “склеить” мелкие в один большой, удалить лишнее и т.п.)
  3. Проверить на наличие ошибок (они могли попасть в репозитарий или образоваться на предыдущем шаге)
  4. Закачать полученное на рабочий сервер.

Всё вроде бы просто, но смущает один момент – экспорт всего и вся. Со времени последнего обновления на сервере в репозитарии обновились 3 файла, а экспортировать нужно всё? Никак нет! Экспортировать будем только то, что изменилось. То есть первый шаг сценария будет выглядеть так:

  1. Получить последнюю версию проекта на сервере – RevFrom
  2. Получить последнюю версию проекта в репозитарии – RevTo
  3. Экспортировать файлы, которые изменились или добавились c RevFrom до RevTo

Версию рабочего проекта, не мудрствуя лукаво, предлагаю хранить в текстовом файле. Например revision.txt. Версию проекта в репозитарии поможет узнать SvnLastRevisionTask. Неясным остался лишь момент – каким образом выяснить какие файлы изменились. Те, кто пользовались TortoiseSVN наверняка знают о чудесной его возможности – сравнить две ревизии и экспортировать “разницу”. Но svn в чистом виде такой возможности не предоставляет. Так что пришлось немного поработать.
(more…)

25.02.08  |  , ,  | 4 comments

phing.tasks.ext.FtpUploadTask

Вычищая комментарии от спама (достали, честное октябрятское) наткнулся на незаслуженно позабытый вопрос товарища altern-a про обещанный ftpupload-таск. Вы спросили – мы ответили: нет, мне не сложно – делюсь.

Собственно сам класс FtpUploadTask.php. И небольшие пояснения.

Код по означенной ссылке необходимо сохранить в файл %PHING_HOME%/classes/phing/tasks/ext/FtpUploadTask.php (Разумеется вы уже знаете что такое Phing и он у вас установлен и готов к использованию).
Для работы требуется установленный в include_path PEAR::Net_FTP, которому в свою очередь необходим php-extension FTP.

На заметку виндузятникам
Первое можно установить посредством выполнения магического пасса в командной строке:
>pear install –all-deps net_ftp
Второе в виндовом php уже вкомпилено.

Параметры, которые принимает task (на всякий случай на моём террибл инглиш ):

Name Type Description Default Required
host String Hostname. n/a Yes
port Integer Ftp server’s port. 21 No
username String Ftp user n/a Yes
password String Ftp password n/a Yes
targetDir String Path to destination directory . (FTP-user’s home) No
mode String Upload FTP-mode. Binary No
cleanDir Boolean Cleanup target directory before upload? False No
overwriteExisten Boolean Overwrite existen files? True No
passiveMode Boolean use passive or active ftp-data connection True No

И пример использования : привожу часть build.xml необходимую и достаточную для запуска таска.

<!-- //skip -->
<taskdef classname="phing.tasks.ext.FtpUploadTask" name="ftpupload" />
<!-- //skip -->
<target name="deploy">
   <ftpupload host="example.com" username="joe" password="$ecr3t" targetDir="/remote/project_home/">
      <fileset dir="/path/to/local/project">
         <include name="**" />
         <exclude name="**/*.dist" />
         <exclude name="src/*" />
      </fileset>
   </ftpupload>
</target>
<!-- //skip -->

Разумеется taskdef удобнее перенести в defaults.properties, для того чтобы не таскать его из проекта в проект.

И снова повторюсь – “таким образом программист может за три часа написать программу, которая сделает за пять минут то, что другой человек делал бы целый час…” ;o)

Technorati Tags: , ,

15.11.07  |  ,  | 4 comments

Phing Is Not GNU

Таким образом программист может за три часа написать программу, которая сделает за пять минут то, что другой человек делал бы целый час…
© Кто-то

“Дорогая, а гладить ты умеешь?”

Много слышал и читал про phing, но пощупать досконально нехватало времени и желания. И вот наконец моё свободное время было потрачено (и не зря) на изучение сего монстра

“Монстром” я называю phing в “хорошем” смысле этого слова – это настоящий кухонный комбайн, СВЧ-печь и стиральная машина в одном флаконе архиве.

Что же это всё-таки такое?. Phing это Ant воссозданный на php. (Вопросы “Чё эта?” и “а нахер?” Вы можете задать непосредственно разработчикам того и другого, а я продолжу…).

Тем кто знает что такое Ant вероятнее всего phing не нужен,тем кто не знает, но интересуется, могу посоветовать хорошую вводную статью, а остальным попытаюсь объяснить вкратце суть явления.

“Но есть способ лучше!”

В процессе разработки чего-либо возникают невероятное количество однообразных операций, которые порядком утомляют.
Как пример из собственной практики – удаление “ненужных” файлов (очистка всемозможных кешей, временных файлов и т.п.), создание структуры директорий (расстановка необходимых прав доступа), удаление debug-кода из скриптов(массовый search-n-replace в определённом наборе файлов), компоновка кучи мелких “инклюдов” в общий файл и много-много подобных мелочей…

Можно конечно всё сделать “вручную”. А можно рутинную работу поручить машине. Одним из способов это сделать являются build-файлы для phing. build-файл представляет собой xml-ку в которой указан проект – совокупность задач (target-ов), которые следует выполнить, а так же последовательность (зависимость – depends в терминах phing) их выполения.

<project name="make_release" basedir=".." default="build">
   <taskdef classname="phing.tasks.ext.PhpStripCommentsTask" name="phpstripcomments" />
   <taskdef classname="phing.tasks.ext.JsLintTask" name="jslint" />
   <target name="clear_cache_dir">
       <delete>
          <fileset dir="cache">
              <include name="*" />
          </fileset>
      </delete>
   </target>
   <target name="lint_before_strip">
      <jslint jslbinary="/usr/bin/jslint" failonerror="true">
          <fileset dir=".">
              <include name="**/*.js"/>
              <exclude name="**/.old_site/**" />
          </fileset>
      </jslint>
    <!-- skip -->
    </target>
    <!-- ....skip -->
    <target name="build" depends="prepare,clear_cache_dir,lint_before_strip,dump_db,copy_src,cleanup_src,remove_debugging,lint_after_strip,simpletests">
    <!-- skip -->
        <mail to="me@mydomain.tld" subject="build complete">
              The build process is a success...
        </mail>
    </target>
</project>

После запуска phing начнёт выполнять default task (в примере – build), и поскольку его выполнить нельзя пока не выполнены depends, то начнёт их делать по указанному порядку… ну и на радостях отправит мне письмо (что конечно лишнее)

“Но и это ещё не всё…”
Спектр задач которые в настоящий момент способен решать phing довольно широк (от файловых операций и строковых манипуляций, до работы с svn, simpletest и phpdoc). Для тех кому зазо исходного набора окажется недостаточно есть замечательная возможность плодить task-и самостоятельно – просто наследуйте новый класс от базового Task и вперёд.
Мне не хватило jslint, jscompress и zndenc – на создание коих было бесследно утрачено минут 15 драгоценного времени. В настоящий момент (ага вот прямо сейчас) обдумываю написание самого аццкого таска – ftpupload (или ftpsync).

Интересный момент – target-ы выполняются строго по порядку и если произойдёт некая непредвиденная ситуация(файл нельзя записать или например как в примере выше в проверяемом коде обнаружится синтаксическая ошибка) другие таргеты выполнятся не будут, выполнение будет прервано exception-ом. Собственно момент интересен тем что можно создавать собственный обработчик этих самых exception-ов, в которых делать “правильные выводы” о том стоит ли продолжать работу или смело “to die if necessary…”.

Другая интересная возможность – делать собственные logger-ы – потому как наблюдать за бурной рабочей деятельностью phing-а в консоли не больно удобно. В стандартной поставки для примера есть AnsiColorLogger, который слегка “приукрашивает” серые терминальные будни. А можно пойти дальше – складывать логи в sqlite например.

“А вы поменяете две пачки обычного порошка на одну пачку необычного?”

Чем хорош именно phing – он написан на php5 – я могу исправить, дополнить и добавить недостающие фичи (Ant несомненно хорош, имеет кучу готовых плагинов, но написан на java, которую я совсем не знаю). Стандартный (g)make откровенно бесит синтаксисом makefile-ов, pake (идея видимо нагло стырена с rake)тоже ничего (хорошего), но уж слишком прост и расширять его возможности довольно муторно :) .
Тонна мелких и крупных shell-perl-php-cmd скриптов, которые я ранее использовал для решения сиюминутных насущных проблем тоже порядком задолбали.
Чем плох – xml как формат build-файлов (хотя на вскидку лучшего предложить ничего не могу, но “аллергия” на xml ещё не прошла) и написан на php5 ;o) – скорость работы оставляет желать лучшего (18 минут на сборку,проверку и упаковку 10-ти мегабайтного проекта на мой взгляд это много).
Но “удобность” всё-таки решает. Так что:

$> pear channel-discover pear.phing.info$> pear install phing/phing

И вперёд…

Technorati Tags: , , ,

20.09.06  |   | 3 comments

Performance Optimization WordPress Plugins by W3 EDGE