# Plik sterujący dla jednego z projektów # # Rozbudowaną architektura testującą, która sprawdza projekt po względem # statycznym (cel "check_valid") i dynamicznym (cel "run_tests"). Te # sprawdzenia są obligatoryjne przy fazie commit w systemie kontroli # wersji (cel "ci"). # # W ten sposób automatycznie egzekwuję zasadę "projekt w systemie # kontroli wersji przechodzi wszystkie zautomatyzowane testy". Inne # automatycznie egzekwowane zasady tu zapisane: # # - nie można instalować na serwerze produkcyjnym z rozgałęzień # (cel "not_in_branch") # - obsługa pliku ze zmianami (cel "cvs_install") # - polityka tworzenia rozgałęzień (cele: "bcreate", "bmerge") # - zgłoszenie rozgałęzienie do kontroli jakości (cel "bverify") - # stosuję konwencję nazewniczą tagów w CVS-ie # $Id: Makefile,v 1.130 2004/01/26 13:38:43 darek Exp $ ###################################################################### # cel sprawdzający poprawność projektu (statyczną, dynamiczną) # i instalujący wersję demo danych w bazie test_rule: testIndexForm.py config.py rights check_valid run_tests demo # uruchomienie testów statycznych check_valid: sh check.sh # uruchomienie testów dynamicznych run_tests: # najpierw testujemy ostatnio modyfikowane moduły time -p python test.py `ls -t \`grep -lr "^def test" *.py\`` ###################################################################### DIST_TGZ=~/proj_name.tgz # prawidłowy sposób zapisywania zmian w systemie CVS # możliwy tylko kiedy przejdą wszystkie testy ci: ready_for_commit test_rule py_compile cvs_commit ###################################################################### # obsługa serwera testowego # debian_all: debian_install debian_download debian_import # zainstalowanie nowej wersji oprogramowania na serwerze testowym debian_install: tar zcf $(DIST_TGZ)\ images/*.gif utils/* upgrade/* *.py *.html *.sql\ *.cgi *.fcgi *.sh *.txt &&\ scp proj_name-debian.sh $(DIST_TGZ) debian: &&\ ssh debian 'sh -v proj_name-debian.sh' # ściągnięcie aktualnej bazy danych z serwera produkcyjnego debian_download: ssh debian '\ set -x;\ scp myapp@server.com:.htpasswd\* ~;\ scp -r myapp@server.com:/var/www/proj_name/config .' ssh myapp@server.com '\ set -x;\ cd /var/www/proj_name/ && python dump.py |\ gzip -c > ~/tmp/proj_name.sql.gz &&\ cat ~/tmp/proj_name.sql.gz &&\ rm ~/tmp/proj_name.sql.gz' |\ ssh debian 'cat > proj_name.sql.gz' # załadowanie obrazu bazy danych i uruchomienie skruptów importujących debian_import: ssh debian '\ set -x;\ cd public_html/proj_name;\ sh utils/create-db.sh $$USER $$USER a;\ zcat ~/proj_name.sql.gz | python mysql.py;\ python upgrade.py | tee upgrade.log' ###################################################################### not_in_branch: cvs st Makefile | awk '/branch/{exit 1}' # instalacja na serwerze proukcyjnym - możliwa tylko z HEAD oracle_install: not_in_branch delay tar zcf $(DIST_TGZ)\ images/* utils/cgi-fcgi upgrade/* *.py *.html *.sql\ *.cgi *.fcgi *.sh *.txt &&\ scp proj_name-oracle.sh $(DIST_TGZ) myapp@server.com:tmp &&\ ssh myapp@server.com 'cd ~/tmp && sh -v proj_name-oracle.sh';\ now=`date +'%Y-%m-%d %H:%M'`;\ branch_name=`cvs st Makefile | awk '/branch/{print "(" $$3 ")"}'`;\ info="$$now $$branch_name $$USER: INSTALL";\ echo $$info >> versions.txt;\ cvs ci -m "$$info" ###################################################################### # statystyki projektu (ilości linii) stats: find . -name '*.py' | sed '/CVS/d' | xargs sed '/^$$/d' | wc -l find . -name '*.sql' | sed '/CVS/d' | xargs sed '/^$$/d' | wc -l find . -name '*.html' | sed '/CVS/d' | xargs sed '/^$$/d' | wc -l # generowanie charakterystyk pokrycia pycover: rm -f coverage.dat python coverage.py `ls -t \`grep -l "^def test" *.py\`` ../pycover/pyviewc.py -e 'usr/lib|/test.py' # statyczna weryfikacja poprawności kodu *.py pycheck: pychecker\ --tuple\ --var\ --allglobals\ --initattr\ --callattr\ --blacklist xmllib\ --maxlines 100\ --maxbranches 20\ --maxreturns 7\ *.py > err # stosunek kod / testy w poszczególnych modułach test-ratio: utils/test-ratio *.py *.sql *.html # wersja lokalna konfiguracji (stacja developerska) # różni się od konfiguracji na serwerze produkcyjnym config.py: workstation.sh install.sh . workstation.sh ###################################################################### # wyszukiwanie globalne s: echo -n 'podaj szukany ciąg znaków: ';\ read a;\ echo "Szukam $$a";\ fgrep -n "$$a" * # usunięcie tymczasowych plików clean: rm -f *.pyc *.pyo cache/* data/* *.cov coverage.dat err rights: chmod 0755 *.cgi *.fcgi utils/* zmianaStanu.py # dedykowany skrypt tworzy indeks projektu pozwalający po nazwie # znaleźć definicję funkcji, klasy, zmiennej tags: *.py *.sql *.html Makefile utils/dtags export LC_COLLATE=en_EN; utils/dtags *.py *.sql *.html | sort -k 1,1 > $@ ###################################################################### # commit wraz z logowaniem cvs_commit: read -p "enter log for this version: " description;\ test -z "$$description" && exit 1;\ now=`date +'%Y-%m-%d %H:%M'`;\ branch_name=`cvs st Makefile | awk '/branch/{print "(" $$3 ")"}'`;\ info="$$now $$branch_name $$USER: $$description";\ echo $$info >> versions.txt;\ cvs ci -m "$$info"; # możemy instalować tylko jeśli wszystkie pliki zostały zapisane w CVS ready_for_install: cvs -n up 2> /dev/null | awk '\ /^\?|^M/ { print "commit file:", $$0; result = 1; }\ END { exit(result); }' # od ostatniego update nie wprowadzano zmian na serwer # wersja lokalna jest wersją aktualną ready_for_commit: cvs -n up 2> /dev/null | awk '\ /^P|^U|^\?|^C/ { print "update file:", $$0; result = 1; }\ END { exit(result); }' # sprawdzenie, czy wszystkie pliki się kompilują py_compile: ls *.py | sed 's/\(.*\)\.py/import \1/' | python -OO rm -f *.pyo # inicjalizacja bazy danych przykładowymi danymi demo: python demo.py run_demo delay: @echo "INSTALUJESZ NA SERWERZE PRODUKCYJNYM ZA 2 SEKUNDY" sleep 2 # zakończenie istniejących procesów FASTCGI r: clean ps x | awk\ '$$5 ~ /python/ && $$6 ~ /fcgi/ {print "kill", $$1}' | sh -v # generowany dynamicznie kod testujący testIndexForm.py: dispatch.py utils/testIndexForm.sh sh utils/testIndexForm.sh > $@ ###################################################################### # status projektu - nazwa rozgałęzienia st: cvs st Makefile # lista istniejących tagów / rozgałęzień blist: @cvs log -h Makefile |\ sed 's/:.*//g' |\ sed -n '/ /p' | sort # utworzenie rozgałęzienia z kodu w podanej chwili czasowej # razem z informacją o tym pozostawioną w HEAD bcreate: @tail versions.txt;\ read -p "date to start (yyyy-mm-dd HH:MM): " start_date;\ read -p "name of new branch [a-z_0-9]+: " branch_name;\ now=`date +'%Y-%m-%d %H:%M'`;\ info="$$now $$USER: ($$branch_name) branch starts from $$start_date";\ echo "$$info" >> versions.txt;\ cvs ci -m "$$info" versions.txt;\ cvs up -D "$$start_date";\ cvs tag -b "$$branch_name" > /dev/null;\ cvs tag -F "$$branch_name-start" > /dev/null;\ cvs up -r "$$branch_name";\ cvs st Makefile;\ # dołączenie rozgałęzienia do HEAD bmerge: blist @read -p "name of existing branch to merge [a-z_0-9]+: "\ branch_name;\ cvs up -j "$$branch_name-start" -j "$$branch_name";\ # zgłosznie odgałęzienia do weryfikacji i instalacji bverify: blist @read -p "name of existing branch to verify [a-z_0-9]+: "\ branch_name;\ cvs tag -Fr "$$branch_name" "$$branch_name-verify" > /dev/null;\