Sotomajor.org.ua - development, photography and a lot of stuff: Використання build-систем в PHP проектах

Звичайно, багато хто стикався з проблемами різної конфігурації проекту для розгортання його на dev і production середовищах. Як мінімум потрібно замінити login, password і database name для доступа к СУБД. На практиці відмінностей получається набагато більше.

Хтось вирішує це правлячи константи руками, хтось будує ліс із if'ів, які в залежності від місця же знаходиться скрипт - підставляють відповідні значення в константи конфігурації. А дехто використовує для таких цілей софт, який, власне, і призначений для цього - build системи. Далі в статті розкажу як це робити на прикладі Apache Ant.

corner icon
2010.07.14 Замки під Львовом. Занедбані і не дуже Zacharovana Desna 2010 -> Litky. People fords the river. 2010.06.05 Винниченко Володимир - Між двох сил 2010.06.18 Lohika Company Day Lviv at night European trip 2010: Budapest -> This thing somehow can rive on the water. European trip 2010: Brussels

Використання build-систем в PHP проектах

2008-11-16 10:41 // // Section:
Apache Ant Logo

Звичайно, багато хто стикався з проблемами різної конфігурації проекту для розгортання його на dev і production середовищах. Як мінімум потрібно замінити login, password і database name для доступа к СУБД. На практиці відмінностей получається набагато більше.

Хтось вирішує це правлячи константи руками, хтось будує ліс із if'ів, які в залежності від місця де знаходиться скрипт - підставляють відповідні значення в константи конфігурації. А дехто використовує для таких цілей софт, який, власне, і призначений для цього - build системи. Далі в статті розкажу як це робити на прикладі Apache Ant.

Для чого це потрібно

Apache Ant - аналог UNIX-утиліти make. Обидва інструмента дозволяють виконати певну послідовність дій, яка є частиною процесу збірки програмного забезпечення. Оскільки в даній статті мова йде про PHP, нам не потрібно виконувати компіляцію, а лише підготувати код для розгортання в певному середовищі.

Така підготовка може включати в себе:

  • Створення тимчасових директорій (наприклад, для логів, кешу, тощо...);
  • Встановлення константам значень які відповідають середовищу;
  • Наповнення бази даних, або інших ресурсів тестовими значеннями (для dev environment);
  • Запуск юніттестів (може бути виконаний як під час збірки проекту, так і після змін в коді);

Що для цього потрібно

Одною із переваг Ant є його кросплатформеність. Він написаний на Java, тому основною вимогою є встановлений в системі JDK. З інсталяцією проблем виникати не повинно, можливі помилки при запуску, які вирішуються встановленням коректного значення для змінної оточення JAVA_HOME.

Після інсталяції можна починати складати файл build.xml. Цей файл в форматі xml описує весь процес збирання вашого проекту. Детально ознайомитися з правилами його складання можна тут.

Приклад

Основними елементами build-файла є properties - властивості, targets - цілі і власне дії. Властивості можут приймати значення та бути використані в інших виразах. Також властивості можуть бути підключені із зовнішніх файлів.

Цілі описують послідовність дій яка має бути виконана. Кожна ціль може залежити від інших, в такому випадку спочатку будуть виконані цілі що вказані в атрибуті depends, а потім залежна ціль, яка їх викликала. В мануалі це все добре розписано, тому краще подивитися на приклад.

xml:
<project name="SomeProject"  basedir=".">
    <property name="build_dir" location="build"/>
    <target name="d.includes">
        <property file="${build_dir}/development.properties"/>
    </target>
    <target name="p.includes">
        <property file="${build_dir}/production.properties"/>
    </target>
    <target name="create_dirs">
        <mkdir dir="${temp_dir}/"/>
        <mkdir dir="${log_dir}/"/>
    </target>
    <target name="generate_code">
        <copy file="${build_dir}/globalGenSource.php" tofile="${conf_dir}/globalGen.php" />
        <replace
            file="${conf_dir}/globalGen.php"
            value="">

            <replacefilter token="@master_db_host@" value="${master_db_host}" />
            <replacefilter token="@master_db_name@" value="${master_db_name}" />
            <replacefilter token="@master_db_user@" value="${master_db_user}" />
            <replacefilter token="@master_db_pass@" value="${master_db_pass}" />
        </replace>
    </target>
    <target name="build" depends="create_dirs, generate_code">
        <echo>Starting build.</echo>
    </target>
    <target name="d.build" depends="d.includes, build" />
    <target name="p.build" depends="p.includes, build" />
</project>

Тут описані наступні цілі:

  • d.includes - підключення файлу з властивостями для development environment;
  • p.includes - підключення файлу з властивостями для production environment;
  • create_dirs - створення директорій;
  • generate_code - встановлення відповідних значень для PHP констант;
  • build - основна ціль, яка включає в себе допоміжні;
  • d.build, p.build - точки входу для development і production білдів відповідно.

Ітак, що ж тут відбувається? Після запуску ant d.build шукається файл build.xml в поточній директорії. Далі шукається ціль d.build в тому файлі. Знайшовши її він бачить що вона залежить від цілей d.includes і build. В межах цілі d.includes, Ant підгружає відповідний файл з властивостями, який виглядає таким чином:

properties:
name=Development build
server_url=http://someproject
root_dir=/home/soto/public_html/someproject
temp_dir=${root_dir}/tmp
log_dir=${root_dir}/logs
conf_dir=${root_dir}/conf
master_db_host="localhost"
master_db_name="photodeer"
master_db_user="root"
master_db_pass=""

Далі йде ціль build, яка залежить від create_dirs і generate_code. З create_dirs все ясно, а generate_code спочатку копіює globalGenSource.php із ./build в директорію проекту, а далі заміняє мітки типу @label@ на відповідні значення з підключеного property файлу:

bash:
soto@y-deer:~/public_html/someproject> cat build/globalGenSource.php
<?php
define('MASTER_DB_HOST', @master_db_host@);
define('MASTER_DB_NAME', @master_db_name@);
define('MASTER_DB_USER', @master_db_user@);
define('MASTER_DB_PASS', @master_db_pass@);
soto@y-deer:~/public_html/someproject> cat conf/globalGen.php
<?php
define('MASTER_DB_HOST', "localhost");
define('MASTER_DB_NAME', "photodeer");
define('MASTER_DB_USER', "root");
define('MASTER_DB_PASS', "");

Після цього керування повертається до цілі build, виводиться повідомлення і процес завершується.

Резюме

Звичайно, це далеко не повний перелік дій які можна виконувати за допомогою Ant. Окрім вбудованих типу replace, echo, copy він може виконати будь-яку системну команду. По мірі росту проекту файл build.xml буде також зростати. Не обов'язково виконувати весь процес з початку і до кінця. Деякі цілі такі як створення/видалення таблиць в БД, видалення тимчасових файлів, запуск юніт-тестів, тощо можуть бути виконані на вже розгорнутому проекті під час його розробки.

  • — Author: Stas Dovgodko · 2008-11-17 15:56 · #

    Собственно для PHP есть Phing – http://phing.info/trac/, явно его не использую но на нем построены билдеры моего любимого ORM Propel :)

    Но, вообще имхо тяжелое решение для указанной задачи, использую бутстрап файл с case $ENV

  • — Author: Сотомайор · 2008-11-17 18:29 · #

    Скажемо так, стаття має лише дати розуміння того що таке є і навіщо воно потрібно. А вибір білдера це справа індивідуальна і залежна від проекту :-)

Add a comment: