Otomatik Commit Mesajları ve PR Açıklamaları Oluşturan Bir CLI Aracı: Geliştirici Verimliliğini Nasıl Artırırsınız?
Yazılım geliştirme süreçlerinde, özellikle ekip çalışmalarında, tutarlı ve açıklayıcı commit mesajları ile Pull Request (PR) açıklamaları yazmak, projenin okunabilirliği ve sürdürülebilirliği açısından kritik öneme sahiptir. Ancak bu süreç genellikle zaman alıcı ve tekrarlayıcı olabilir. Geliştiriciler, üzerinde çalıştıkları kodun özünü birkaç cümleye sığdırmak, yapılan değişiklikleri doğru bir şekilde özetlemek ve proje standartlarına uygun bir dil kullanmak konusunda sıklıkla zorlanırlar. Peki, bu süreci otomatikleştirmek ve geliştirici verimliliğini artırmak mümkün müdür? İşte tam da bu noktada, yapay zeka destekli, komut satırı arayüzü (CLI) tabanlı bir araç devreye giriyor. Bu makalede, kendi commit mesajı ve PR açıklaması oluşturma CLI aracınızı nasıl geliştireceğinizi, temel kavramlardan başlayarak ileri düzey özelliklere kadar adım adım keşfedeceğiz. Bu sayede, kod yazmaya daha fazla zaman ayırırken, dokümantasyon yükünüzü hafifleteceksiniz.
Neden Otomatik Commit Mesajları ve PR Açıklamalarına İhtiyaç Duyarız?
Modern yazılım geliştirme pratiklerinde versiyon kontrol sistemleri (VCS), özellikle Git, projelerin bel kemiğini oluşturur. Git’i etkili kullanmanın temel taşlarından biri de anlamlı commit mesajları yazmaktır. Her bir commit, projenin tarihçesinde bir dönüm noktasıdır ve bu dönüm noktasının ne anlama geldiğini net bir şekilde açıklamalıdır. Benzer şekilde, Pull Request (PR) veya Merge Request (MR) açıklamaları, yapılan değişikliklerin kapsamını, neden yapıldığını ve ne gibi etkileri olduğunu ekip üyelerine aktarmanın en önemli yoludur. Ancak, bu süreçler genellikle geliştiriciler için bir yük haline gelebilir ve birçok dezavantajı beraberinde getirebilir.
Öncelikle, zaman kaybı önemli bir faktördür. Geliştiriciler, bir özelliği tamamladıktan veya bir hatayı giderdikten sonra, ne yazdıklarını, neden yazdıklarını ve bu değişikliğin neyi çözdüğünü düşünmek için ekstra zaman harcarlar. Bu düşünme süreci, bazen birkaç dakikadan çok daha fazlasını alabilir, özellikle karmaşık değişikliklerde. Bir geliştiricinin haftada ortalama 10-15 commit yaptığını düşünürsek, bu küçük zaman dilimleri birikerek önemli bir iş gücü kaybına yol açar. Ayrıca, bu süreç tekrarlayıcı olduğu için motivasyon düşüklüğüne de neden olabilir; geliştiriciler, “yine mi açıklama yazacağım?” hissine kapılabilirler. Bu durum, nihayetinde daha az açıklayıcı veya aceleyle yazılmış commit mesajlarına yol açar ki bu da projenin uzun vadeli sağlığı için olumsuz bir durumdur.
İkinci olarak, tutarsızlık ve standartlaşma eksikliği büyük bir problem yaratır. Farklı geliştiriciler, farklı stillerde, farklı detay seviyelerinde veya farklı dillerde commit mesajları yazabilirler. Bu durum, proje geçmişini incelerken veya belirli bir değişikliği ararken büyük zorluklara neden olur. Örneğin, bir ekip üyesi “bug fix” yazarken, diğeri “hata düzeltmesi” yazabilir ve bir başkası ise sadece “fix” diyebilir. Bu tür tutarsızlıklar, projenin tarihçesini anlamsız bir metin yığınına dönüştürebilir. Bir standart belirlemek ve buna herkesin uymasını sağlamak zorlu bir yönetim görevidir ve genellikle tam olarak başarılamaz. Otomatik bir araç, bu tutarsızlığı ortadan kaldırarak tüm commit mesajlarının belirli bir format ve içerik standardına uygun olmasını sağlar, bu da projenin bütünlüğünü ve okunabilirliğini artırır.
Üçüncü olarak, kod inceleme (code review) süreçleri bu açıklamaların kalitesinden doğrudan etkilenir. İyi yazılmış bir PR açıklaması, kod inceleyicinin değişikliklerin amacını, kapsamını ve etkilerini hızlıca anlamasına yardımcı olur. Eğer PR açıklaması yetersizse, inceleyici kodu daha derinlemesine incelemek zorunda kalır, bu da inceleme süresini uzatır ve yanlış anlamalara yol açabilir. Otomatik olarak oluşturulan, detaylı ve bağlamı doğru yansıtan açıklamalar, inceleme sürecini hızlandırır, hata oranını düşürür ve ekip içi iletişimi güçlendirir. Özellikle büyük ve karmaşık projelerde, bu tür bir otomasyon, geliştirme döngüsünü önemli ölçüde hızlandırabilir ve genel proje kalitesini yükseltebilir.
Son olarak, proje geçmişinin netliği ve hata ayıklama (debugging) kolaylığı da otomatik açıklamaların faydaları arasındadır. Bir hata ortaya çıktığında veya belirli bir özelliğin nasıl eklendiği anlaşılmak istendiğinde, projenin Git geçmişi incelenir. Açıklayıcı commit mesajları, hangi değişikliğin ne zaman ve neden yapıldığını anlamayı kolaylaştırır. Bu sayede, hataların kaynağını bulmak veya eski bir özelliği yeniden anlamak çok daha hızlı ve verimli hale gelir. Özetle, otomatik commit mesajları ve PR açıklamaları, sadece geliştiriciye zaman kazandırmakla kalmaz, aynı zamanda projenin genel kalitesini, sürdürülebilirliğini ve ekip içi işbirliğini de önemli ölçüde artırır. Bu yüzden, bu tür bir CLI aracı geliştirmek, modern yazılım ekipleri için vazgeçilmez bir yatırım haline gelmektedir.
Yapay Zeka ve Doğal Dil İşleme (NLP) Bu Süreçte Nasıl Bir Rol Oynuyor?
Otomatik commit mesajları ve PR açıklamaları oluşturma fikri kulağa hoş gelse de, bu açıklamaların bağlamı doğru anlaması ve insan benzeri bir dil üretmesi kritik bir zorluktur. İşte tam bu noktada yapay zeka (AI) ve özellikle doğal dil işleme (NLP) teknolojileri devreye girer. Son yıllarda büyük dil modellerindeki (Large Language Models – LLM) gelişmeler, bu tür otomasyonları gerçeğe dönüştürmüştür. GPT-3, GPT-4, Claude ve benzeri modeller, metin anlama, özetleme, çeviri ve metin üretme gibi karmaşık NLP görevlerinde insan seviyesine yakın performans sergileyebilmektedir.
Bir CLI aracının, kod değişikliklerini analiz ederek anlamlı bir açıklama üretebilmesi için öncelikle kodun ne yaptığını “anlaması” gerekir. Bu, geleneksel programlama yaklaşımlarıyla son derece zordur çünkü kodun semantiğini (anlamını) ve bağlamını kavramak, basit anahtar kelime eşleştirmelerinin ötesine geçer. Yapay zeka modelleri, bu görevi üstlenir. Örneğin, bir dosyada yapılan eklemeleri ve çıkarmaları (git diff çıktısı) analiz ederek, bu değişikliklerin hangi amaca hizmet ettiğini çıkarabilirler. Yeni bir fonksiyon eklendiğinde, AI modeli fonksiyon adını, parametrelerini ve içindeki mantığı inceleyerek fonksiyonun ne işe yaradığını özetleyebilir. Benzer şekilde, bir hata düzeltmesi yapıldığında, eski kod ile yeni kod arasındaki farkları algılayarak hatanın ne olduğunu ve nasıl düzeltildiğini açıklayabilir.
NLP’nin buradaki rolü, AI modelinin bu “anlama” sürecini gerçekleştirmesini sağlamaktır. Kod diff’i, model için bir girdi (input) görevi görür. Model, bu girdi üzerindeki doğal dil işleme tekniklerini kullanarak, kodun içindeki anahtar kelimeleri, yapıları, yorumları ve hatta değişken isimlerini analiz eder. Örneğin, bir değişkenin adının kullaniciAdi olması veya bir fonksiyonun adının veritabaninaKaydet olması, model için önemli ipuçlarıdır. Bu ipuçlarını birleştirerek, model değişikliğin genel temasını ve amacını belirler. Ardından, bu çıkarımları kullanarak, istenen formatta (örneğin, Conventional Commits standardına uygun) ve belirli bir dilde (Türkçe veya İngilizce) bir commit mesajı veya PR açıklaması üretir. Bu metin üretim süreci, modelin milyonlarca metin verisi üzerinde eğitilmiş olmasından kaynaklanır; bu sayede doğal ve akıcı bir dil kullanabilir.
Prompt (istem) mühendisliği de bu süreçte kritik bir öneme sahiptir. AI modeline ne kadar iyi bir istem verirseniz, o kadar kaliteli bir çıktı alırsınız. Örneğin, sadece kod diff’ini vermek yerine, “Bu Git diff’ini analiz ederek, Conventional Commits standardına uygun, Türkçe bir commit mesajı oluştur. Mesajın başına değişiklik tipini (feat, fix, docs vb.) ekle, ardından kısa bir başlık ve detaylı bir açıklama sun,” gibi daha spesifik bir istem, modelin beklentilerinizi daha iyi anlamasını sağlar. Modelden sadece bir özet istemekle, detaylı bir analiz ve açıklama istemek arasında büyük farklar vardır. NLP’nin sağladığı bu yetenekler sayesinde, geliştiriciler artık manuel olarak metin yazmak yerine, AI’ın ürettiği taslakları hızlıca gözden geçirip, gerekirse küçük düzeltmelerle kullanabilirler. Bu da hem zaman kazandırır hem de daha tutarlı ve yüksek kaliteli dokümantasyon sağlar. Yapay zeka, geliştirme süreçlerinde sadece kod yazımına değil, aynı zamanda kodun açıklanması ve belgelenmesi süreçlerine de devrim niteliğinde katkılar sunmaktadır.
Kendi CLI Aracınızı Adım Adım Nasıl Geliştirirsiniz?
Kendi otomatik commit mesajı ve PR açıklaması oluşturma CLI aracınızı geliştirmek, düşündüğünüzden daha kolay olabilir. Bu bölümde, Python kullanarak böyle bir aracı adım adım nasıl inşa edeceğinizi anlatacağız. Python, zengin kütüphane ekosistemi ve okunabilir sözdizimi sayesinde bu tür bir araç için mükemmel bir seçimdir. Amacımız, kullanıcının git diff çıktısını otomatik olarak alıp, bir yapay zeka modeline göndererek anlamlı bir commit mesajı veya PR açıklaması oluşturmasını sağlayacak bir araç geliştirmektir.
Proje Yapısı ve Gerekli Araçlar
Bir CLI aracı geliştirirken iyi bir proje yapısı kurmak, kodun düzenli ve bakımı kolay olmasını sağlar. Temel olarak, projemiz bir ana betik (script) ve yardımcı fonksiyonları içeren modüllerden oluşacak. Python’da CLI uygulamaları için argparse veya Click gibi kütüphaneler kullanabiliriz. Bu makalede, daha basit ve temel bir yaklaşım için argparse kütüphanesini kullanacağız, ancak daha karmaşık CLI’lar için Click daha güçlü seçenekler sunar.
Gerekli kütüphaneler:
argparse: Komut satırı argümanlarını (örneğin,--typeveya--pr) işlemek için Python’ın yerleşik kütüphanesi.subprocess: Git komutlarını (git diff) çalıştırmak ve çıktısını almak için.requests: Yapay zeka API’si ile iletişim kurmak için (örneğin, OpenAI API’si).python-dotenv: API anahtarı gibi hassas bilgileri güvenli bir şekilde yönetmek için.
Proje dizin yapımız şöyle olabilir:
my-commit-cli/
├── cli.py
├── .env.example
├── .gitignore
└── requirements.txt
cli.py ana betiğimiz olacak. .env.example, çevre değişkenlerinin nasıl tanımlanacağını gösterirken, .gitignore Git'in görmezden gelmesi gereken dosyaları (örn: .env) belirtecek. requirements.txt ise projemizin bağımlılıklarını listeleyecek. İlk adım olarak, requirements.txt dosyamızı oluşturalım ve gerekli kütüphaneleri ekleyelim:
requests
python-dotenv
Bu kütüphaneleri yüklemek için terminalinizde aşağıdaki komutu çalıştırabilirsiniz:
pip install -r requirements.txt
Ardından, .env dosyanızda API anahtarınızı tanımlayacaksınız:
OPENAI_API_KEY="sizin_openai_api_anahtarınız"
Bu temel kurulumla, artık Git değişikliklerini algılama ve yapay zeka entegrasyonu adımlarına geçmeye hazırız. Projemizin iskeletini oluşturduk ve gerekli tüm bağımlılıkları yükledik. Bu başlangıç, aracın modüler ve genişletilebilir olmasını sağlayarak, gelecekte yeni özellikler eklemeyi veya mevcutları geliştirmeyi kolaylaştıracaktır. Ayrıca, .env kullanımı sayesinde hassas bilgilerimizin kaynak kodunda yer almasını engelleyerek güvenliği artırmış olacağız. Bu, özellikle açık kaynak projelerde veya ekip içinde çalışırken büyük önem taşır.
Git Değişikliklerini Algılama ve Ayıklama
CLI aracımızın ilk ve en önemli adımı, Git deposundaki değişiklikleri tespit etmek ve bu değişikliklerin detaylarını almaktır. Bu bilgilere dayanarak yapay zeka modeli, anlamlı commit mesajları veya PR açıklamaları üretecektir. Git, bu tür bilgileri almak için güçlü komutlar sunar ve biz de bu komutları Python'ın subprocess modülü aracılığıyla çalıştıracağız.
Temel olarak kullanacağımız Git komutu git diff olacaktır. Bu komut, çalışma dizinimizdeki değişiklikleri veya belirli bir commit ile HEAD arasındaki farkları gösterir. Bizim senaryomuzda, henüz commit edilmemiş (staged veya unstaged) değişiklikleri analiz etmek isteyebiliriz. Bunun için git diff HEAD komutunu kullanabiliriz. Eğer sadece staged (sahnelenmiş) değişiklikleri almak istersek, git diff --cached veya git diff --staged kullanırız. PR açıklamaları için ise genellikle son birkaç commit'in birleşimini veya belirli bir dal (branch) ile ana dal (main/master) arasındaki farkı alırız. Bu makalede, basitlik adına, mevcut çalışma dizinindeki staged ve unstaged değişikliklerin bir özetini almak için git diff komutunu kullanacağız.
cli.py dosyamızda Git komutunu çalıştırmak için aşağıdaki fonksiyonu tanımlayabiliriz:
import subprocess
import os
def get_git_diff():
"""
Mevcut Git deposundaki staged ve unstaged değişikliklerin diff çıktısını alır.
"""
try:
# Sadece staged değişiklikleri almak için --cached kullanılabilir.
# Tüm değişiklikleri (staged + unstaged) almak için 'git diff' yeterlidir.
# PR açıklaması için belirli bir branch'ten diğerine diff alınabilir:
# subprocess.check_output(['git', 'diff', 'main..feature-branch'])
diff_output = subprocess.check_output(['git', 'diff'], text=True)
if not diff_output.strip():
print("Git deposunda henüz commit edilmemiş bir değişiklik bulunamadı.")
return None
return diff_output
except subprocess.CalledProcessError as e:
print(f"Git komutu çalıştırılırken bir hata oluştu: {e}")
return None
except FileNotFoundError:
print("Git komutu bulunamadı. Lütfen Git'in yüklü ve PATH'inizde olduğundan emin olun.")
return None
# Fonksiyonu test etmek için:
if __name__ == "__main__":
# Bu kısmı sadece test amaçlı kullanıyoruz, ana CLI akışında farklı çağırılacak.
# Mevcut dizinin bir Git deposu olduğundan emin olun.
if os.path.exists(".git"):
diff = get_git_diff()
if diff:
print("--- Git Diff Başlangıcı ---")
print(diff[:500]) # İlk 500 karakteri göster (çok uzun olmaması için)
print("--- Git Diff Sonu ---")
else:
print("Diff alınamadı veya değişiklik yok.")
else:
print("Bu bir Git deposu değil. Lütfen bir Git deposu içinde çalıştırın.")
Yukarıdaki kod bloğu, get_git_diff fonksiyonu ile git diff komutunu çalıştırır ve çıktıyı bir string olarak döndürür. text=True parametresi, çıktının metin olarak işlenmesini sağlar. Olası hataları (Git'in yüklü olmaması veya komutun başarısız olması gibi) yakalamak için try-except blokları kullanıyoruz. Özellikle, git diff çıktısının boş olması durumunda, henüz commit edilmemiş bir değişiklik olmadığı anlamına gelir ve bu durumu kullanıcıya bildirmemiz gerekir.
PR açıklamaları için ise genellikle iki farklı dal (branch) arasındaki farkı almak isteriz. Örneğin, feature-branch dalındaki tüm değişiklikleri main dalına göre özetlemek için git diff main..feature-branch komutunu kullanırız. Bu, CLI aracımızın esnekliğini artıracak ve farklı senaryolara uyum sağlamasını sağlayacaktır. Diff çıktısı, yapay zeka modelimiz için ana veri kaynağıdır. Bu çıktının ne kadar detaylı ve doğru olduğu, AI'ın üreteceği mesajın kalitesini doğrudan etkileyecektir. Bu nedenle, diff alma mekanizmasının sağlam ve hatasız çalışması büyük önem taşır. Bu adım tamamlandığında, aracımız artık kod değişikliklerini başarıyla okuyabiliyor demektir ve yapay zeka entegrasyonuna hazırız.
Yapay Zeka Entegrasyonu: Commit Mesajı ve PR Açıklaması Oluşturma
Git değişikliklerini başarıyla algıladığımıza göre, şimdi sıra bu değişiklikleri anlamlı commit mesajları ve PR açıklamalarına dönüştürmek için yapay zekayı kullanmaya geldi. Bu adımda, bir yapay zeka API'si ile (örneğin, OpenAI'ın GPT modelleri) nasıl etkileşime geçileceğini ve etkili prompt (istem) mühendisliğinin önemini ele alacağız. OpenAI API'si, doğal dil işleme görevleri için güçlü ve erişilebilir bir seçenektir.
İlk olarak, .env dosyamızda tanımladığımız API anahtarını Python betiğimizde kullanabilmek için python-dotenv kütüphanesini yüklememiz ve yapılandırmamız gerekiyor:
# cli.py dosyasının başına ekleyin
from dotenv import load_dotenv
load_dotenv() # .env dosyasındaki değişkenleri yükler
import os
import requests
import json
OPENAI_API_KEY = os.getenv("OPENAI_API_KEY")
OPENAI_API_URL = "https://api.openai.com/v1/chat/completions" # GPT-3.5/4 için chat endpoint
def generate_ai_message(diff_content, message_type="commit"):
"""
Verilen Git diff içeriğini kullanarak AI'dan commit mesajı veya PR açıklaması oluşturur.
"""
if not OPENAI_API_KEY:
print("Hata: OPENAI_API_KEY çevre değişkeni ayarlanmamış.")
return None
# Prompt mühendisliği: AI'dan ne istediğimizi açıkça belirtmek.
if message_type == "commit":
system_prompt = "Sen bir yazılım geliştiricisinin Git commit mesajlarını yazmasına yardımcı olan bir yapay zeka asistanısın. Sadece verilen Git diff içeriğine dayanarak, Conventional Commits (type: subject) standardına uygun, kısa ve açıklayıcı Türkçe bir commit mesajı oluştur. Mesajın başına değişiklik tipini (feat, fix, docs, style, refactor, test, chore gibi) ekle, ardından kısa bir başlık ve detaylı bir açıklama sun. Eğer değişiklik basitse, sadece başlık yeterli olabilir. Cevabın sadece commit mesajı olsun, başka bir şey içermesin."
user_prompt = f"Aşağıdaki Git diff'i için commit mesajı oluştur:\n\n{diff_content}"
elif message_type == "pr":
system_prompt = "Sen bir yazılım geliştiricisinin Pull Request (PR) açıklamalarını yazmasına yardımcı olan bir yapay zeka asistanısın. Sadece verilen Git diff içeriğine dayanarak, detaylı, okunabilir ve Türkçe bir PR açıklaması oluştur. Açıklama, yapılan değişiklikleri, neden yapıldığını ve potansiyel etkilerini içermelidir. Başlık, Değişiklikler, Neden Yapıldı ve Etkileri gibi bölümler kullan. Cevabın sadece PR açıklaması olsun, başka bir şey içermesin."
user_prompt = f"Aşağıdaki Git diff'i için Pull Request açıklaması oluştur:\n\n{diff_content}"
else:
print("Hata: Geçersiz mesaj tipi belirtildi. 'commit' veya 'pr' olmalı.")
return None
headers = {
"Authorization": f"Bearer {OPENAI_API_KEY}",
"Content-Type": "application/json"
}
payload = {
"model": "gpt-3.5-turbo", # Daha güncel modeller için 'gpt-4o' veya 'gpt-4-turbo' kullanılabilir
"messages": [
{"role": "system", "content": system_prompt},
{"role": "user", "content": user_prompt}
],
"temperature": 0.7, # Yaratıcılık seviyesi (0.0 - 1.0 arası)
"max_tokens": 500 # Üretilecek metnin maksimum uzunluğu
}
try:
response = requests.post(OPENAI_API_URL, headers=headers, data=json.dumps(payload))
response.raise_for_status() # HTTP hatalarını kontrol et
response_data = response.json()
ai_message = response_data['choices'][0]['message']['content'].strip()
return ai_message
except requests.exceptions.RequestException as e:
print(f"API isteği sırasında bir hata oluştu: {e}")
return None
except KeyError:
print(f"API yanıtı beklenenden farklı: {response_data}")
return None
# Test amaçlı kullanım (ana CLI akışına entegre edilecek)
if __name__ == "__main__":
# Örnek diff içeriği (gerçekte get_git_diff() fonksiyonundan gelecek)
sample_diff = """
diff --git a/main.py b/main.py
index e69de29..7d3000f 100644
--- a/main.py
+++ b/main.py
@@ -0,0 +1,5 @@
+def factorial(n):
+ if n == 0:
+ return 1
+ else:
+ return n * factorial(n-1)
"""
# commit_message = generate_ai_message(sample_diff, message_type="commit")
# if commit_message:
# print("\nOluşturulan Commit Mesajı:")
# print(commit_message)
# pr_description = generate_ai_message(sample_diff, message_type="pr")
# if pr_description:
# print("\nOluşturulan PR Açıklaması:")
# print(pr_description)
generate_ai_message fonksiyonu, diff_content ve message_type (commit veya pr) parametrelerini alır. En kritik kısım, system_prompt ve user_prompt değişkenleridir. system_prompt, yapay zekaya rolünü ve beklentilerimizi anlatır. Ne kadar açık ve detaylı bir prompt verirseniz, o kadar iyi sonuçlar alırsınız. Örneğin, Conventional Commits standardına uygun bir commit mesajı istediğimizi veya PR açıklamasının hangi bölümleri içermesi gerektiğini belirtmek, çıktının kalitesini artırır.
requests.post metodu ile OpenAI API'sine bir HTTP POST isteği gönderiyoruz. İstek başlıklarında API anahtarımızı, gövdesinde ise
