Monday, March 31, 2014

Projelerde Git

Projelerde kullanilan bazi Git numaralari ve tavsiyeleri:

Eger Wifi uzerinden git push yapmaya calisip Connection refused hatasi alirsaniz, tamir icin .ssh/config dosyasina girip

Host github.com
  Hostname ssh.github.com
  Port 443

yazmak yeterli.

N commit oncesi (mesela 10) ile en son commit arasinda hangi dosyalar degisti:

git diff --name-only HEAD~10

Git Pull

Artik Github cogu projede kullanilan bir servis, onu baz alan bazi tavsiyeleri paylasmak iyi olur. Tipik bir tur kullanim soyle olabilir, kullanici

git add *
git commit -m 'vs'
git push origin master 

ile son kodu gondermektedir, ve gerektiginde son kodlari almak icin git pull yapmaktadir. Eger cakisma var ise, bu durumda Git birlestirme (merge) yapmaya ugrasir ve cakismalari programcinin cozmesini ister. Cozme sonrasi git push isler, fakat git log, yani nelerin yapildigini gosteren kayit pek hos gozukmez.

Alternatif yontem, ortak depodan en son kodlari alirken git pull yerine git fetch kullanmaktir. Bu kullanim en son dallari (branch) alir, fakat yerel dosyalar uzerinde degisim yapmaz. Sonra git rebase origin/master yapariz, bu komut bizim kodumuzu biraz once alinan son kod uzerine "istifler" / geri calar (replay). Git bunu oyle yapar ki sanki bizim kodumuz mevcut olanin uzerine yazilmistir, sanki o kodu o kod biter bitmez hemen almisiz, ve onun uzerinde bizimkini yazmisiz gibi... Bu durumda da cakismalar gorulebilir muhakkak, onlar varsa cozulur; Sonra git push daha once yapildigi gibi yapilir.

Mevcut Olmayan Asiri Buyuk Dosya

Belki gelistirme dizini icinde gecici pkl dosyalari uretiliyor, ve bunlardan bazilarini yanlislikla git add ve commit ile kendi deponuza koydunuz. Sonra git push sirasinda hatayi farkettiniz, git rm ile dosyayi sildiniz. Fakat push hala "bu dosya cok buyuk" diye yakiniyor. Problem Git tum degisiklikleri teker teker yollamaya ugrasiyor - dosya eklemesi, sonra onu silmesi. Tabii eklerken yine yakiniyor. Cozum, surada.

git filter-branch --force --index-filter 'git rm --cached --ignore-unmatch [BUYUK DOSYA, * VS ISARETLERI KULLANILABILIR]' --prune-empty --tag-name-filter cat -- --all

git push origin --force --all

Dal Yapisi (Branch Structure)

Bizim kullandigimiz bir yaklasim soyle: master yani ana dal her zaman "isleyen kodu" temsil eder. Yani master'da ne var ise, sonuc (production) makinasinda o var demektir. Bu baglantinin sIkI tutulmasi iyi olur, yani master'a gonderilen her sey, aninda isleme konmalidir.

Gelistirme icin master'dan dallanarak mesela bir dev (gelistirme) dali kullanabiliriz, bu daldan her programci kendisi icin ayri bir dal da yaratabilir, bu onlara kalmis. Fakat kodcular arasi entegrasyon icin dev dali kullanilir. Cakismalar vs var ise bu dalda cozulur, master a gondermeden once entegrasyon testleri bu dal  uzerinden isletilir. Eger sonuc iyi bulunursa buradan master'a birlestirme (merge) yapilir. Onemli nokta sudur: artik kimse master dali uzerinde gelistirme yapmaz. Ana master dali artik commit edilen bir sey degil, merge edilen bir seydir yani.

Gelistirme dali icin onu yaratiriz, ve kullanmaya baslariz,

git checkout dev

ile gecis yapariz. Kodlama vs bitince commit edilir. Sonra git push ile Github'a gonderilir. Birlestirme icin

git checkout master
git merge dev
git push origin master

yapilir.

Daha Sofistike Dal Yapilar

http://nvie.com/posts/a-successful-git-branching-model/

Ustteki yazida tarif edilen sudur: gelistirme (dev) ve surum (master) iki, surekli orada olan dal vardir. Gelistiriciler belli ozellikleri gelistirmek icin dev'den dal ayirirlar. Master her zaman en son, isler kodu temsil etmektedir, sonuc ortaminda isleyen budur. Surum yapmak icin dev'den isminde versiyon no'su tasiyan yepyeni bir dal yaratilir, ve bu dalda artik yeni ozellik eklenmez, sadece ufak tefek entegrasyon puruzleri cozulur, hatalar onarilir.




Github Projesini Yerel Dosyalardan Sifirlamayip Yaratmak

Bazen GH'daki projemizi ismen ayni tutsak bile icerigini yerel diskimizden en son dosyalardan yaratip, Git tarihini sifirlamak isteyebiliriz. Sebepler, belki Git kayitlarinin oldugu .git icindeki dosyalar bozulmustur (corrupted), ya da Git tarihine asiri buyuk dosyalar commit edilmistir, her ne kadar onlarin git rm ile silmissek bile, hala tarihte duruyor olurlar, bu da .git dosyalarini sisirir. Onlari tarihten silebiliriz tabii, ama bazilarini kacirmis olabiliriz. Her halukarda sifirdan baslamak icin pek cok sebep olabilir. Bunu yapmak icin

cd [PROJE DIZINI]
.git dizinini sil
git init
git add .
git commit -m 'Initial commit'
git remote add origin - burada git@github.com:kullanici/proje.git .. diye giden projenize ait olan url
git push --force --set-upstream origin master

Dikkat: ustteki adimlari takip edince eger projenizdein GH uzerinde dallanma (branch) yapmis olan insanlarla baglanti tamamen kesilir. Cunku bu noktada tarihi sildiniz, ve neredeyse yeni bastan bir proje yaratmis oldunuz.

Ustteki adimlarin iyi bir tarafi projenizin GH seviyesindeki bilgileri hala ayni kalir; alinan yildizlar, takipciler, vs. degismez.

Bu yaziya ekler olacak.

Wednesday, March 19, 2014

Web ve JSON ile Servis Arayuzu, UWSGI

Herhangi Python bazli bir yazilimi dis dunyaya (servis olarak) acmak icin en basit seceneklerden biri HTTP servisi uzerinden JSON iledir, ayrica bizi mantikli URL'ler kullanmaya tesvik eden REST yaklasimi iyi olur. En alt seviyede web servisi olarak mikro servis Flask olabilir. Flask'in guzel bir ozelligi mantikli URL ile Python fonksiyonu iliskisini etiket (annotation) ile halledebilmesi. Kurmak,

sudo pip install flask

Kod

from flask import Flask, url_for, jsonify
from flask import request, Response
app = Flask(__name__)

@app.route('/')
def api_root():
    return 'Merhaba'

@app.route('/test/url', methods=["PUT", "POST"])
def rq():
    data = request.get_json(force=True)   
    articles = sorted(data['liste'])
    return jsonify({'liste': liste})

if __name__ == '__main__':
    app.debug = True
    app.run(host="localhost", port=8080)


Baslatiriz,

python main.py 

Ve test icin localhost:8080 ziyaret edilir. Merhaba mesaji gorulur. Sonra curl ile

curl -H "Content-Type: application/json" -d '{"liste":[3,2,1]}' \
http://localhost:8080/test/url


ozel URL'e JSON gonderilir. Kodun tek yaptigi listeyi alip siralamak, yani 3,2,1 siralanip 1,2,3 olarak geri gonderilecek.

Simdi buyuk olcegi dusunelim. Komut satirindan basit sekilde baslatilan Flask olceklenemez. Fakat Flask onunde yuk dagitici olarak gorev yapabilecek ve Flask'e rahat entegre olabilen bazi secenekler var. Bunlardan biri UWSGI.

http://projects.unbit.it/downloads/

2.0.3 indirin. python setup.py build ve sudo python setup.py install ile kurun.

Kullanmak icin main.py olan dizinden,

nohup sudo uwsgi --processes 4 --http :8080 -s /tmp/mysock.sock \ --module main --callable app  --py-autoreload 1 \
--logto /tmp/main.log  --pidfile /tmp/main.pid \
> /tmp/cour.log 2> /tmp/cour.err < /dev/null &

Ustteki cagri birden fazla surec icinde kodunuzu isletime sunar. Erisim noktasi 8080 port'u uzerinden her istek baska bir surece gonderilir boylece olceklenme halledilir. Secenek --py-autoreload 1 ile sureclerden biri cokerse otomatik olarak tekrar baslatilmasini soyluyoruz, boylece dayaniklilik acisindan onemli bir avantaj elde ediyoruz.

Ayrica --pythonpath  ile ek paket gerekiyorsa onlarin nereden yuklenmesi gerektigini set edebiliriz. Bu paketler setup.py build install ile kurulabiliyorsa tabii bu secenege gerek yok, ama bazen gerekebilir.

Durdurmak icin

uwsgi --stop=/tmp/main.pid

uwsgitop

Unlu Unix top gibi sadece uwwsgi sureclerini izlemek icin bir arac yazilmis,

https://github.com/unbit/uwsgitop

Yanliz uwsgi sureclerini izleyebilmek icin ozel bir sekilde baslatmak lazim, secenek  --stats /tmp/stats.socket eklenmeli. Sonra

sudo uwsgitop /tmp/stats.socket

ile arac baslatilir.

Not: Bu arada literature gore artik LAMP paketi degismis (ki bu harfler Linux, Apache, MySQL, PHP'yi temsil ediyordu), artik LEMP olmus. E harfi nginx'i temsil icin kullaniliyor, bilindigi gibi nginx "engine x" olarak okunuyor, ve onun E'si A yerine, yani Apache yerini almis. Ilginc bir gelisme. Bizim icin de PHP yerine Python var tabii - hala P!