Miesięczne archiwum: Styczeń 2014

Phing, czyli zautomatyzuj swoje zadania #3

Trochę czasu mineło od ostatniego i w końcu udało mi się znaleźć chwilę na opisanie kolejnych elementów Phinga – filtrów i maperów.

Filtry

Filtry pozwalają na wykonywanie różnych operacji na zawartości plików – na przykład usuwanie komentarzy z kodu. Wywołanie filtrów grupuje się w tagu <filterchain>, przykład poniżej:

	<copy todir="kopia" overwrite="true">
		<fileset dir=".">
			<patternset refid="ogolne" />
		</fileset>
		<filterchain>
			<stripphpcomments />
		</filterchain>
	</copy>

Przykładowy kod definiuje operację kopiowania plików (zdefiniowanych w elemencie <patternset> o ID: „ogolne” do katalogu „kopia”. Oprócz zwykłego kopiowania pliki są przetwarzane przez łańcuch filtrów. W tym wypadku zawierający jeden filtr, który usuwa z plików komentarze PHP.

W momencie pisania tego posta Phing dostarczał 19 wbudowanych filtrów, listę można znaleźć w dokumentacji. Natomiast z popularniejszych filtrów myślę, że należy wymienić:

Z praktycznego punktu widzenia filtry są bardzo przydatne, ale mogą powodować pewne problemy w połączeniu z systemem kontroli wersji – o tym co można poradzić napiszę w dalszej części.

Mapery

Efektem działania filtrów jest zmiana zawartości plików, natomiast mapery działają analogicznie, ale z nazwami plików. W momencie przygotowywania wpisu Phing dostarczał 6 maperów. W moim odczuciu najbardziej przydatne są:

  • GlobMapper – podmiana nazw plików według prostych wzorców;
  • RegexpMapper – to samo, ale z wykorzystaniem wyrażeń regularnych we wzorcach.

Użycie maperów odbywa się w analogiczny sposób jak filtrów – w ramach jakiejś operacji plikowej (przykład zaczerpnięty z oficjalnej dokumentacji):

<copy todir="/tmp">
  <mapper type="glob" from="*.php" to="*.php.bak"/>
  <fileset refid="someid" />
</copy>

Praktyczny przykład użycia

Za dobry przykład użycia Phinga (filtry, mapery) i systemu kontroli wersji uważam generowanie plików konfiguracyjnych projektu.

Idea opiera się na plikach o rozszerzeniu .dist (kwestia umowna). Do systemu kontroli wersji trafiają pliki „szablonowe” (.dist), tak żeby ich struktura mogła być śledzona. Z drugiej strony, aby nie zawierały konkretnych informacji (np. dostęp do bazy danych). W tych plikach zamiast wartości pojawiają się Phingowe odwołania do zmiennych. Utworzenie działającego pliku konfiguracyjnego polega na:

  1. skopiowaniu pliku
  2. zmianie rozszerzenia z .php.dist na .php
  3. podstawieniu wartości w miejsce wywołań zmiennych

Plik config/Config.php.dist:

<?php

class Config
{
	const DB_HOST = '${config.db.host}';
	const DB_NAME = '${config.db.name}';
	const DB_USER = '${config.db.user}';
	const DB_PASSWORD = '${config.db.password}';
}

Plik srodowisko.properties:

config.db.host = localhost
config.db.name = site
config.db.user = siteuser
config.db.password = tAjNeHaSlO

Plik build.xml:

<?xml version="1.0" encoding="UTF-8"?>

<project name="HelloWorld" default="hello">
	<property file="srodowisko.properties" />

	<target name="configure">
		<copy todir="config">
			<fileset dir="config">
				<include name="*.php.dist" />
			</fileset>
			<mapper type="glob" from="*.php.dist" to="*.php" />
			<filterchain>
				<expandproperties />
			</filterchain>
		</copy>
	</target>

</project>

Po uruchomieniu komendy phing configure skrypt podstawi wartości z pliku właściwości, zmieni rozszerzenie i utworzy nowy plik, który można dołączyć do kodu projektu. Takie podejście daje dużą elastyczność, ponieważ cała konfiguracja środowiska może być zapisana w jednym pliku. Dzięki temu projekt można przekonfigurować czy to pod kątem środowiska produkcyjnego, czy developerskiego podstawiając jeden plik i wydając jedną komendę (a można to jeszcze uprościć). Zaletą jest również to, że w systemie kontroli wersji znajdują się pliki, bez wartości zależnych od środowiska. W tym celu, dla powyższego przypadku należy dodać do listy plików ignorowanych przez system kontroli wersji plik Config.php.

Przydatne linki: