rulu ruru

post Jenkins, Django, virtualenv, mercurial (a Debian)

July 30th, 2011

Filed under: programming — starenka @ 19:40
Tags: , , , , , , ,

 Nedávno jsem rozcházel testovací stroj pro Django projekty postavenej na Jenkinsu a jelikož informace o tomhle setupu jsou tak nějak polovičatý a navíc porozházený po internetech, rozhod’ jsem se to malinko rozepsat. Jenkins můžete s minimálním úsilím zaměnit za Hudson a Mercurial za git, Bazaar, SVN či kýhošlaka. Debian samozřejmě taky nehraje zásadní roli.

Nejdřív rozjedeme Jenkins:

echo ‘deb http://pkg.jenkins-ci.org/debian binary/’ >> /etc/apt/sources.list
aptitude update; aptitude install jenkins

Pokud je vše v pořádku, doinstalujeme pár pluginů. Takže nakopnout browser na http://localhost:8080/pluginManager/available a zaškrtnout: Mercurial Plugin (na Mercurial), Hudson Setenv Plugin (podpora ENV proměnnejch), Cobertura Plugin (coverage reporty), Violations (hlášení o prasení kódu z pylint a spol.), ChuckNorris Plugin (ehm) a Green Balls (ano, taky vám přijde zelená kulička po úspěšným buildu lepší než modrá?)

Až dorestartujete (jo, je to v Jáááááááááávěěěěěěěěěě), šup nastavit Mercurial na http://localhost:8080/configure

Cesty se samozřejmě můžou lišit, čili Executable zjistíte pomocí which hg a Installation directory vypreparujete z dpkg -L mercurial. To je co se týče Jenkinsu samotnýho všechno a tak jady vytvořit novej (Build a free-style software project) projekt http://localhost:8080/view/All/newJob

 

 

Obrázek je za sto slov, takže jen telegraficky. V sekci SCM nastavit cestu k repozitáři projektu, Jenkins tak díky Poll SCM (Build trigger), bude vědět, že do větve někdo pushnul novou revizi a spustí build. Schedule si nastavte dle potřeb, syntax je ne-nepodobnej crontabu, samozřejmě se nemusíme bát použít nápovědu. Jakmile, se Jenkins dozví, že přibyla nová revize, sám si ji potáhne. (Občas se mu to ale nepovede, v takovým případě nezbejvá nic jinýho než wipenout celej workspace)

V Build Environment de fakto aktivujeme virtualenv v adresáři .env (viz níže) a volitelně do PHYTONPATH přihodíme další potřebný knihovny (tady 3rdparty pro modifikované knihovny třetích stran a ourawesomelibs kde jsou naše skvělý knihovny sdílený napříč projekty). 

V sekci Build se děje většina tohole celýho mažiku. Myslím, že tady nemusím recitovat slovo od slovo, co ten skript dělá, ale kdyby to byl někdo chabrus na bash, tak pro jistotu: Zjistíme, jestli už máme vytvořený virtualenv a případně ho vytvoříme. Pak si naklonujeme nebo updateneme knihovny zmíněný výše. Nakonec použijeme pipinku na doinstalovaní knihoven, který náš projekt potřebuje. Preferuju dva soubory - jeden s knihovnama potřebnýma pro projekt a další, kde jsou knihovny potřebný pro otestování, lint, coverage a napojení na Jenkins (requirements_test). Po sestavení (updatnutí) envu se spustí samotný testy.

Po buildu si necháme ještě pěkně vymalovat code coverage (Cobertura), prohřešky naprásknutý pylintem (Violations) a hlavně taky výsledky testů (JUnit test result report). Všechno předatlovat z obrázku výše.

A to mám jako všechno přepisovat, jo? 

Moc toho na psani neni, ale ok:

#ENV vars
PATH=${WORKSPACE}/.env/bin:$PATH
PYTHONPATH=${WORKSPACE}/.env/LIBS/3rdparty:${WORKSPACE}/.env/LIBS/ourawesomelibs:$PYTHONPATH

##bash

if [ -d ".env" ]; then
    echo "**> Virtualenv already exists"
else
    echo "**> Creating virtualenv"
    virtualenv .env
fi

echo "**> UPDATING LIBS"
for lib in "3rdparty" "ourawesomelibs"; do
   if [ ! -e "$WORKSPACE/.env/LIBS/" ]; then
      mkdir "$WORKSPACE/.env/LIBS/"
   fi

   cd "$WORKSPACE/.env/LIBS/"

   if [ -e "$WORKSPACE/.env/LIBS/$lib" ]; then
      cd "$WORKSPACE/.env/LIBS/$lib"
      hg pul
      hg up
   else
      hg clone ssh://chrootuser@repo.myawesomcompany.cz/home/chrootuser/repos/LIBS/$lib
   fi
done

cd "$WORKSPACE"
pip install -r requirements.pip
pip install -r requirements_test.pip
python manage.py jenkins –settings=settings.test

 

Počkej, počkej! A co máš teda v těch requirements_test a jak vypadá ten Django setting pro test?

Mimo obvyklejch nastavení je tady pár věcí, který je třeba nastavit kvůlivá Jenkinsu. Podotýkám, že tohle je setting importující z nějakýho base nastavení a přepisuje jen pár nastavení:

TEST_RUNNER = ‘django_nose.NoseTestSuiteRunner’
#PROJECT_APPS = (,) #if defined, only defined tests will be started

#excluded apps
TEST_EXCLUDES = (    
   #django itself
    ‘django.contrib.auth’,
    ‘django.contrib.contenttypes’,
    ‘django.contrib.sessions’,
    ‘django.contrib.sites’,
    ‘django.contrib.admin’,
    ‘django.contrib.sitemaps’,
   #3rd party
    ‘django_extensions’,
   #test stuff
    ‘django_nose’, ‘django_jenkins’, ’south’,
)

SOUTH_TESTS_MIGRATE = False

INSTALLED_APPS += (‘django_nose’, ‘django_jenkins’,’south’)
 

Díky TEST_EXCLUDES můžeme vyřadit některý appky, nebo konkrétní testy. Nemusíme tedy zbytečně čekat na testy origoš Django appek apod. Do INSTALLED_APPS přihodíme věci potřebný pro testování, který by nám na produkci nebo někde jinde zbytečně strašily. Pokud by nám na prázdný testovací db z nějakýho důvodu haprovaly migrace, mužeme použít SOUTH_TEST_MIGRATE.

Co se týče knihoven, requirements_test říká:

south
coverage
nose
pylint
git+git://github.com/starenka/django-jenkins.git#egg=django_jenkins
#django_jenkins

Pokud nechceš/nepotřebuješ používat EXCLUDED_TESTS, bude lepší použít originál django_jenkins. Ten (můj) fork z GitHubu má právě tuhle fičuru backportlou z django_hudson, ale negarantuju, že to budu udržovat. Ostatní je jasny, coverage na generování coverage statistik, nose jako runner a pylint na statistiky Violations.

No a to je asi víceméně všechno. Ano, dalo se toho napsat rozhodně míň. Na druhou stranu se toho dalo napsat taky o dost víc. Doufám, že i tohle někomu aspoň trochu pomůže. Kdyby nastaly nějaký komplikace, nebojte se ozvat v komentářích.

 

 

post Python, php a ruby lint precommit hook pro Bazaar

March 6th, 2010

Filed under: programming — starenka @ 18:47
Tags: , , , , , ,

Jsou situace, kdy prostě někdě neco ujede, někde se něco připlete a ne vždy to člověk v IDE bere na vědomí. Provádění syntax checku před komitem mi přijde jako docela dobrej nápad. Unit test a TDD křídla, který mi určitě rádi poví, že tohle už by mělo součástí testů atd. blatytyblaa prosím, aby mě nechali žít v bludu, že testy někdy prostě třeba nejsou. Hooky pro Bazaar se píšou fakt krásně, takže ho spíchnout je docela zábava. Hooky jsou normální pluginy, takže patří do ~/.bazaar/plugins. Komentovat těch pár řádek netřeba. V případě PHP a Ruby, kde se používá CLI, binárka a grep bude asi trošku skřípot na Windows, ale imho nebude problém to pořešit jinak (jsem línej a navíc mě to netíží). Bastlení zdar.

post Ako v Prahe?

January 24th, 2009

Filed under: programming — starenka @ 20:51
Tags: , , , , ,

Na DPP byl bagrem vyštrachán pěkný seznam čidel, moniturujících teplotu vzduchu, silnice a rychlost větru na místech v Praze (abych to uved’ na pravou míru - bagr hledal ceny jízdenek a našel čidla. To, že ceny jízdenek mimo P0 nenašel je nasnadě…). Stránka se mi celkem zamlouvá. Ne, že bych nějak dal na teploty, ale v souvislosti s trochou volnýho času, kterýho se mi teď dostává, jsem se rozhod’ konečně zkusit první “Hello čidlo!” v Ruby. První kontakt mě docela znechutil, protože jak se zdá Ruby < 1.9.1 trpí dětskejma nemocema spojenýma s délkou řetězce v unicode. Za pomoci deepje a Googlu mi trvalo půl hodiny, než se mi to podařilo vyřešit. Zlatý prciny (PHP,Python).

#!/usr/bin/ruby

$KCODE="u"
require ‘uri’
require ‘net/http’
require ‘jcode’

data = "http://www.dpp.cz/flash/data/meteo.xml"
xml = Net::HTTP.get_response(URI.parse(data).host, URI.parse(data).path)
if xml.code == ‘200′ then
    matches = xml.body.gsub(‘0.0′,‘—’).
        scan(%r{.*?<name>(.*?)</name><air>(.*?)</air><road>(.*?)</road><wind>(.*?)</wind>}mi)
    puts "\nčidlo\t\tvzduch\tsilnice\tvítr\n[kde]\t\t[°C]\t[°C]\t[m/s]\n————————————-"
    for place in matches
        padd = place[0].jsize > 7?"\t":"\t\t"
        puts place[0]+padd+place[1]+"\t"+place[2]+"\t"+place[3]
    end
else puts ‘!!ERR: Failed to fetch ‘+data
end

post Shell-fu: tvůj blbovníček na málo používané příkazy

November 28th, 2008

Filed under: linux, programming, python — starenka @ 09:57
Tags: , , , , ,

Nedávno jsem na cinanove blogu viděl zajímavej skript, kterej sloužil jako prasátko (pokladnička) málo používanejch příkazů. Docela mě nápad nadchnul a jelikož mi pojetí moc nevyhovovalo, rozhodnul jsem se napsat si vlastní. O co jde. Skript uloží tebou zadaný příkazy do souboru (sqlite) a dovolí je (p)otagovat. Položky je následně možné kopírovat do schránek (KDE3/4,X,MacOS). Samozřejmě je můžeš i mazat. Na bonus můžes vypsat všechny tagy nebo položky a samozřejmě hledat.

Skript je dobré udělat spustitelným, symlinknout do $PATH a symlink zbavit přípony. Tím člověk docílí možnosti spustit skript jednoduše odkudkoliv. Jak používat? Nápověda se zobrazí po zadání shell-fu -h. Hledat dá ednoduše shell-fu vyraz resp. shell-fu "vyraz s mezerou".

Pokud nemáte, bude třeba následující balíčky: python, python-sqlite, sqlite3, sqlalchemy a volitelně xclip.

post Alenka v říši Excelu - jak dostat název sloupečku

November 3rd, 2008

Filed under: php, programming — starenka @ 21:49
Tags: , ,

Pokuď někdo generoval XLSko pomocí jinak dobře našláplýho projektu PHPExcel, jistojistě narazil na fakt, že data se ukladají po buňkách(!). Na tom zase není nic moc až tak tragickýho, až na fakt, že musíte nějak vygenerovat i souřadnici buňky. Já jsem zrovna potřeboval procházet buňky od A až po XY a tak vznikla tahle lehce retardovaná funkce. Budiž možná někomu prospěšná. PS. Pokud někdo přišel na způsob jak ukládat data třeba po sloupečkách nebo snad dokonce po řádkách, nechť mě osvítí v komentářích. 

function make_column_name($start_row,$add)
{
    $len = strlen($start_row);
    if(!is_int($add)) return false;
    if($len > 2 || $start_row == ) return false;
   
    $start_row = strtoupper($start_row);
    $last_ord = ord($start_row[$len-1]);
    $first_ord = ($len == 1)?false:ord($start_row[0]);
    $first_ret_ord = ($len == 1)?65:$first_ord;
    $to_z = 90-$last_ord;
   
    if($add <= $to_z) return ($first_ord)?chr($first_ord).chr($last_ord+$add):chr($last_ord+$add);
    else
    {
        $add -= ($to_z+1);
        return chr($first_ret_ord+floor($add/26)).chr(65+($add%26));
    }
}
Next Page »
ruldrurd
© starenka 2oo7, cute alien monster by noizcut, original theme by Laurentiu Piron - customized by starenka | proudly powered by WordPress