Amikor változtatni kell a Drupal kódján (2)

Hojtsy Gábor képe

Érdekes módon éppen a változtatásokról szóló tipp-kettős előző részének megjelenése napján vált elérhetővé a Lullabot Podcast tizenhatodik része, melyben Jeff Robins készít interjút Dries Buytaert-tel, a Drupal alapítójával. Ebben hangzik el a következő párbeszéd:

Jeff Robins: Don't hack Drupal, if you are hacking the code, you are doing something wrong.
Dries Buytaert: Either you are doing something wrong, or core needs to be extended.
Jeff Robins: [...] but then some security update comes out, or a new version of Drupal comes out, you can't upgrade, because your hacks will break everything.

Most arra a kérdésre próbálom megadni a választ, hogy mit tehetünk, ha mindenképpen saját módosításokat kell alkalmaznunk, de ezeket a frissítésekkel is meg szeretnénk tartani. A megoldás természetesen nem olyan egyszerű, mint egy klasszikus Drupal frissítés, de aki módosít a kódon, annak ezt vállalnia kell.

Melyik Drupal verziót használjuk?

Ha a legújabb hibajavításokkal szeretnénk élni, akkor könnyen lehet, hogy elvesztjük a biztos tudatunkat arról, hogy mégis melyik Drupal verziót használjuk. A Weblabor esetében például jelenleg úgy foghatjuk meg a használt verziót, hogy a Drupal 4.6-os ágon valamilyen dátummal bezárólag aktuálisak a fájljaink. A szükség esetén megjelenő 4.6.x-es kiadások követése mellett a folyamatos hibajavításokat is érdemesnek tartjuk alkalmazni, így valószínű, hogy amit használunk, annak nincs is hivatalos verziószáma. Még ha lenne is, akkor sem lehet megállapítani a fájlok alapján, hogy pontosan melyik verzióval állunk szemben (hacsak nem vezetjük következetesen egy jegyzetben, hogy melyik verzióra frissítettünk legutóbb).

Így kell egy eszköz, ami megmondja, hogy milyen dátumból kell kiindulni. Végig kell nézni minden fájlt, amiben a fejlesztői (CVS) verziónak megfelelő információ található, beleértve a Drupal rendszerbeli legutóbbi módosítás dátumát is. Ezt magunk is megtehetjük, de az alábbi saját fejlesztésű szkript automatizálja a feladatot:

// Grab all files with possible CVS Id data
$files = find_drupal_files();

$cvsids = array();
$latest = '';

// Go over the files and collect CVS Id data
foreach ($files as $filename) {
$content = join('', file($filename));
if (preg_match('!\\$Id: ([^\\$]+) Exp \\$!', $content, $found)) {
$cvsids[$filename] = $found[1];
if (preg_match('!\\d{4}/\\d{2}/\\d{2} \\d{2}:\\d{2}:\\d{2}!', $found[1], $date)) {
if (strtotime($date[0]) > strtotime($latest)) {
$latest = $date[0];
}
}
}
else {
$cvsids[$filename] = 'n/a';
}
}
print "LATEST;$latest\n";
foreach($cvsids as $name => $id) {
print substr($name, 2) . ";$id\n";
}

// Recursively go over possible Drupal files
function find_drupal_files($root = '.') {
$folders = glob($root . '/*', GLOB_ONLYDIR);
$files = glob($root . '/*.{php,inc,txt,module,theme,engine,mysql,pgsql,install}', GLOB_BRACE);
if (file_exists($root . '/.htaccess')) {
$files[] = $root . '/.htaccess';
}
foreach($folders as $folder) {
if (!in_array($folder, array('.', '..'))) {
$files = array_merge($files, find_drupal_files($folder));
}
}
return $files;
}
?>

Ezt a Drupal gyökerébe téve, és onnan lefuttatva megkapjuk CSV formában a fájlok verzió azonosítóit, és legutóbbi fejlesztői módosítási dátumait. A szkript megkísérli a legutóbbi dátumot kiválasztani. Ebben azonban nem szabad vakon bízni. Ha kiegészítő modulokat is telepítettünk, érdemes azoktól eltekinteni a legutóbbi dátum megállapításakor. Hiszen valószínű az alaprendszert és a kiegészítőket külön frissítjük, illetve lehet, hogy egy kiegészítő jóval későbbi dátummal rendelkezik, mint amikor az alaprendszert legutóbb frissítettük. Ez indokolja a CSV formátumot, amit így tudunk importálni kedvenc táblázatkezelőnkbe, és szűrhetjük az elemeket, sorrendezhetünk, és könnyedén kiválaszthatjuk a legutóbbi frissítés dátumát.

Így kiderítettük, hogy mikori a Drupal rendszerünk.

Változáskövetés

Követnünk kell a változtatásainkat. Erre a legkézenfekvőbb eszköz egy saját célra telepített Subversion, CVS vagy más változáskezelő rendszer. Ha eléggé szerencsések vagyunk, hogy egy ilyet az eszköztárunkban tudhatunk, akkor már félig megoldottuk a problémát. Ezzel persze csak a saját módosításainkat követhetjük, illetve a frissítések fájlokra tett hatását ellenőrizhetjük.

Feltételezem viszont, hogy olvasóimnak nincs verziókezelő rendszer a tarsolyában, és szerencsére a változáskövetés esetünkben enélkül is megvalósítható. A Drupal.org CVS szervere ugyanis segítségünkre van mindenben. A megállapított dátumnak megfelelő kódot kell először is letöltenünk a szerverről. Attól függően, hogy milyen CVS klienst használunk, ez más-más módon történik. Én parancssori klienst alkalmaztam. Tegyük fel, hogy a megállapított dátumunk 2005. december 13. és a Drupal 4.6-os kódra van szükségünk. Az alábbi parancs segítségével kaphatjuk meg.


$ cvs -z6 -d:pserver:anonymous:[email protected]:/cvs/drupal co -r DRUPAL-4-6 -D "2005-12-13" drupal

Ezzel kaptunk egy tiszta módosítatlan Drupal forráskódot. Most nincs más dolgunk, mint megállapítani a saját Drupal kódunk, és a tiszta Drupal kód eltéréseit, hogy a változtatásainkat egyértelműen azonosíthassuk. Erre a célra én a Meld nevű programot használtam, de nagyon hasonlóan használható a WinMerge is Windows rendszert alkalmazóknak.

Most hogy tételesen látjuk a változtatásainkat, érdemes egy pillanatra végiggondolni mindegyiknek a létjogosultságát, és amennyiben megtartásuk mellett döntünk, dokumentáljuk mindegyiket az előző részben bemutatott konvenciók szerint. Ez még nagyon meghálálja magát a későbbi kódfrissítéseknél.

Frissítsünk

A változtatásaink azonosítása számos előnnyel jár, de leginkább azért van rá szükség, hogy megkezdhessük a kódfrissítést. Készítsünk egy másolatot az előbbi tiszta Drupal verzióról az összes extra CVS könyvtárral együtt. Ennek a másolatnak a fájljait írjuk felül a saját módosított fájljainkkal. Ezek után futtassuk le a CVS frissítő parancsát továbbra is a 4.6-os ágon maradva, de kérve a legaktuálisabb fájlokat:


$ cvs update -r DRUPAL-4-6

A megjelenő üzenetek között a C jelű fájlokra kell különösen figyelmet fordítanunk, mert ezekben a saját módosításainkat és a Drupal forráskód módosításait a CVS nem tudta összefésülni, és mindkét verziót berakta a fájlba speciális jelzésekkel. Nyissuk meg ezeket a fájlokat bármilyen szerkesztő programban és eseti jelleggel magunk döntsük el, hogy mi lesz a helyes új kód. Ha minden ilyen konfliktust megoldottuk, futtassunk le még egy ilyen update parancsot, és figyeljük meg, hogy csak M jelű fájlunk maradt-e. Ezek az általunk módosított fájlok, amik a frissítéssel összefésülve megtartották a változtatásainkat.

Még nem vagyunk készen

Mivel a kódfrissítés és összefésülés elkészült, egyszerűen felülírhatnánk a webhelyünk forráskódját az új kóddal. Én azonban azt javaslom, hogy ne siessük el, hanem vegyük elő a fent használt különbség vizsgáló programunkat, és ezúttal a frissült kód és a webhelyünk forráskódja között tekintsük át a változtatásokat. Így látni fogjuk, hogy milyen módosítások kerültek a Drupal rendszerbe. Ezek egyrészt adott esetben sminkünk vagy kiegészítő modulunk működésének javítását is szükségessé tehetik. Másrészt pedig ha valami elromlik a friss kód gyakorlatba ültetése után, akkor több tippünk lesz, hogy mégis mi mehetett tönkre, mi változott egyáltalán.

Biztonsági mentés

Végül pedig, mielőtt az új kódot hadrendbe állítanánk, ne felejtsünk el biztonsági mentést készíteni a webhelyünk forráskódjáról és az adatbázisról. Ha valamit elszúrtunk volna, akkor arra még mindig visszatérhetünk.

Hozzászólások

Őry Máté képe

szép, összeszedett és tőled megszokottan jó minőségű cikksorozat. viszont szerintem legalább ilyen fontos a módosítások elkerülése téma. ez még angolul sincs tökéletesen dokumentálva (szerintem). majd próbálok ezzel foglalkozni amíg te ezen töröd magad :)

Hojtsy Gábor képe

Megpróbáltam olyat dokumentálni, amit sokszor inkább ördögi dolog bélyegzéssel elkerülnek az emberek, így pácban hagyva azt, akinek mégis szüksége lenne a saját módosítására. A hook_form_alter() és társai irányvonal részemről is előnyben van, a változtatásaink áttekintésekor a Weblaboron is többmindent másképp oldottunk meg, ezért próbáltam a gondolkodás fontosságát kiemelni az előző részben. Én sem szeretek belenyúlni a kódba, de ha már meg kell tennie valakinek, akkor jó ha tudja, hogy nem teljesen elveszett területen van.

Őry Máté képe

szóval egyetértek veled, kell ez is. és visszaolvasva tényleg eléggé hangsúlyoztad.