Git hook fájlok futtatása fájl társítással
Bár tudom, hogy legtöbbetek Linux alatt fejleszt, de azért remélem, hogy vannak néhányan, akik hozzám hasonlóan Windows-t használnak, és nekik hasznos lehet ez a blogbejegyzés.
Nem egy tipikus probléma, de azért előfordul, hogy Windows alatt szükség van a Git shell nyújtotta szolgáltatásokra. Nálam ez a akkor merült fel, amikor találtam egy pre-commit hookot (a commit előtt automatikusan lefutó Git bash parancsokat tartalmazó kis fájl), ami a benne megadott MySQL adatbázist dumpolta. Az adatbázis szerkezetének mentésével lehetőség nyílik az adatbázis verziókövetésére, ami, valljuk be, nagyon hasznos dolog. Ami nekem nem tetszett ebben a hookban, hogy minden egyes commit előtt lefut, ezért aztán megoldást kerestem, hogy hogyan tudnám dupla kattintással futtatható formába hozni.
Próbálkoztam a Windows Script Hosttal, ezzel viszont az a gond, hogy bár a mysqldump.exe
lefut, számomra ismeretlen okból nem jön létre a .sql
fájl. Próbáltam debuggolni, kevés sikerrel. A másik probléma a WSH-val, hogy nincs lehetőség a sed
használatára. A sed
-re azért van szükség, mert az adatbázis egy-egy táblájának tartalmát a mysqldump
egyetlen sorba teszi bele, így a Gittel nagyon nehéz nyomon követni az egyes rekordok változását. A sed segítségével ezeket a hosszú sorokat sikerült úgy eltördelnem, hogy minden sornak egy-egy rekord feleljen meg. Így már könnyen nyomon követhető, hogy történt-e új rekord felvétele, vagy már létező rekord módosítása, illetve törlése.
Végül úgy döntöttem, hogy hagyom a Windows Script Hostot, és megpróbálom a már működő hook fájlomat valahogy futtatható formába hozni. A .hook
kiterjesztéshez társítottam a Git basht. Ezek után a Google-höz fordultam, ami nem adott használható találatot a témában. Utána próbáltam a git/bin
és a git/cmd
alatt található .exe
és .cmd
fájlokhoz társítani a .hook
-ot, mind kevesebb sikerrel.
Végül a megoldáshoz az ötletet az a felfedezés adta, hogy lehetőség van a Git bash-be fájlokat vonszolni. Ilyenkor a fájl útvonala jelenik meg, és ha nyomunk rá egy entert, akkor a fájl tartalma lefut. Ezután már csak össze kellett dobni egy .bat
fájlt, amit lehet társítani a .hook
kiterjesztéshez:
if not exist %1 exit
set bash=C:\Program Files (x86)\Git\bin\bash.exe
"%bash%" --login -i -c "exec "%1""
Végül pedig a .hook
fájl, amivel az adatbázis mentését végzem:
#!/bin/sh
cd "D:/creation/software developer/projects/webshop-refactoring-project/document root/WebShop";
cd "$(git rev-parse --show-toplevel)"
rm -f "WebShop/DataBase/backup.sql"
exec "C:/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump.exe" --skip-comments -u root --password=root webshopdb |sed 's$),($),\n($g' > "WebShop/DataBase/backup.sql"
exit
Zárszónak annyit, hogy aki Gitet használ verziókezelésre, annak mindenképp érdemes megismerkedni a hookokkal, mert nagyon hasznos dolgokat lehet velük megvalósítani. PHP esetében többek között lehetőség van commit előtt a PHPUnit futtatására úgy, hogyha a unit testek elbuknak, akkor az megakadályozza a commitot. Ezen kívül lehetőség van olyan javascriptes build készítésére, ami összefűzi és zsugorítja az aktuális projekt fájljait, és ezek után akár még teszteli is őket. És ez még csak a jéghegy csúcsa… :-)
■
Continuous integration
Erre a Continuous Integration való, nem commit előtti a hookok: a fejlesztésben elég zavaró, ha várnom kell arra, hogy dolgozhassam tovább. Ha nem akarsz egy Jenkinst beüzemelni, akkor is megteheted, hogy a központi repóba teszel egy post-receive hook-ot, ami jelez egy szolgáltatásnak, hogy újabb commit érkezett, buildelje a rendszert. De a Jenkins jobb.
No majd utánanézek. Az a
Kérdés:
Hogyan teszteled, amit kódoltál, ha nincsenek az osztályaid összetákolva egyetlen js fájllá? Persze nem muszáj mindezt commit-hoz kötni...
mi ezt ugy oldottuk meg anno
- mod_rewrite-bol elkapta a kod, ha az osszecsomagolt css/js re erkezett keres, de az nem volt ott.
- bedobta a webappba egy bizonyos kontrollernek a kerest, ami on-the-fly vegrehajtotta ugyanazt a csomagolast, amit amugy is megcsinalnank, es visszaadta ezt a kliensnek.
ettol nyilvan lassabb volt teszt kornyezetben a kod futasa, de cserebe azonnal tudtal tesztelni mindenfele js/css kod modositast, nem kellett ujrabuildelni hozza a statikus fajlokat.
ps: be lehetett azt is kapcsolni, hogy ne az osszecsomagolt asset-eket huzza be a site, ez meg js/css debugolasnal jott jol, konnyebb kiszurni a hibat, ha nem egy sorban van minden :]
ps2:
mai fejjel mar en is ugy csinalnam, hogy a packing is a ci build resze (volt olyan project ahol ezt igy is csinaltuk), es a fejlesztoi kornyezetben a kulonallo nem minify-olt js/css van hasznalatban, a ci-bol meg ugyis folyamatosan frissul a kod az integracios kornyezetbe, ott pedig tesztelheto, ha esetleg a csomagolasban lenne valami bug.
Tyrael
Teszt -> commit
Először tesztelj, aztán commitolj, nem fordítva. ;)
Jó, de ha beteszed a
Ehhez kellene egy segítség
Pont jó a cikk, csak az én esetemre keresek egy választ. Gitem meg van és van phpunit is. Létrehoztam a phpunit futattásához egy scriptet, a következőt használtam fel: Git és phpunit. Ebben leírja, hogy windows alatt a php -f parancsot futtassam le a fájllal. A fájl meg van. A pre-commit hook-ba bele írtam és mégsem fut le, csak kiírja, hogy "php -f fájlnév". Hol rontom el?
Új téma
hát először próbáld ki, hogy
ha nem, akkor muszáj lesz valamelyik exe fájlra (php.exe, php-win.exe) hivatkoznod... ha a githubos emulált linux alól teszed, akkor valszeg a php.exe, ha windows-os parancssorból, akkor meg a php-win.exe