Kod tabanını okumaya tek bir soruyla başlayın

Bir refactoring öncesinde klasörlerin tamamını okumak yerine değişikliğin etkileyeceği tek bir davranışı seçin. Bu rehberin sorusu şu: EnvDoctor audit komutunda bir ortam değişkeni kullanımı nasıl bulunuyor ve bu bulgu CLI çıkış koduna nasıl dönüşüyor? Böylece giriş noktasını, veri dönüşümlerini ve dışarıdan gözlenen sonucu aynı haritada takip edebiliriz.

Örnek, bana ait açık kaynak EnvDoctor deposunun 25e43e45683180775d3a8e891bb1bc157ae0222a commit'ine dayanıyor. Kaynak okumaları ve aşağıdaki davranış testleri 7 Ekim 2026'da Python 3.14.7 ve ripgrep 15.2.0 ile çalıştırıldı. Bu sürümün CLI çıktısı 0.2.0; Python gereksinimi en az 3.12. Sonuçlar küçük deneme dosyalarına aittir, üretim performansı veya tüm deponun test kapsamı değildir.

Kaynak sürümünü sabitlemek, bugün gördüğümüz satırların yarın değişen main dalıyla karışmasını önler. Aşağıdaki komutlar yeni bir deneme kopyası oluşturur; mevcut çalışma deponuzda çalıştırmayın. Python, Git ve rg komutlarının kurulu olması gerekir.

Terminal
git clone https://github.com/umutgungorr/envdoctor.git envdoctor-reading
cd envdoctor-reading
git checkout --detach 25e43e45683180775d3a8e891bb1bc157ae0222a
python --version
rg --version
rg --files src

Giriş noktası ve çağıranları rg ile bulun

Önce pyproject.toml içindeki console script kaydını ve src/envdoctor/__main__.py dosyasını okuyun. Paket komutu envdoctor.main:main fonksiyonuna bağlanıyor; python -m envdoctor da aynı main fonksiyonuna gidiyor. Arama sonucunda bir isim görmek, o fonksiyonun bütün çalışma zamanı çağıranlarını bulduğumuz anlamına gelmez. Bu örnekte aramayı kaynak kodunu okuyarak doğruluyoruz.

Aşağıdaki ilk arama, __main__.py:3 içe aktarımını, main.py:12 ve :14 bağımlılıklarını, :225 handler tanımını, :236 audit_codebase çağrısını ve :323 audit yönlendirmesini verdi. İkinci aramada auditor.py:68 tek dosya tarayıcısını, :86 satırdaki regex eşleşmesini, :101 klasör denetimini ve :110/:116 tarayıcı çağrılarını görüyoruz. Satır numaraları yalnızca sabitlenen commit için geçerlidir.

-F, aranan metni regex yerine olduğu gibi ele alır; -e birden fazla metni aynı taramada arar; -n satır numarası gösterir. Kapsamı src/envdoctor ile sınırladık. rg varsayılan olarak bazı gizli ve ignore edilmiş dosyaları atlar; bir sonucun bulunmaması, projenin tamamında o davranışın olmadığına tek başına kanıt değildir.

Terminal
rg -n -F -e 'from envdoctor.main import main' -e 'from .auditor import audit_codebase' -e 'from .parser import parse_env_file' -e 'def handle_audit' -e 'res = audit_codebase' -e 'return handle_audit' src/envdoctor

rg -n -F -e 'def scan_file_for_env_keys' -e 'pat.finditer(line)' -e 'def audit_codebase' -e 'scan_file_for_env_keys(' -e 'missing_from_env =' src/envdoctor/auditor.py

Import listesini davranış ve veri haritasına çevirin

main önce CLI seçeneklerini ayrıştırıyor, sonra audit için handle_audit fonksiyonuna yönlendiriyor. Handler, seçilen .env dosyasını parse_env_file ile okuyup yalnızca anahtar kümesini audit_codebase'e geçiriyor. audit_codebase hedef dosyaları buluyor; scan_file_for_env_keys uzantı ve satır filtrelerinden sonra PATTERNS listesindeki regex'leri uyguluyor. Bu sürüm AST çözümleyicisi kullanmıyor.

Haritadaki oklar yalnızca import bağımlılığı değil, doğrulanmış çağrı ve veri dönüşümleridir. CodeReference; anahtarı, dosya yolunu, satır numarasını ve kısa kaynak parçasını taşır. audit_codebase bu referanslardan unique_referenced_keys kümesini oluşturur; bilinen anahtarlarla farkını missing_from_env, ters farkını stale_in_env olarak döndürür. Handler JSON raporunu üretir ve missing_from_env boş değilse 1, boşsa 0 döndürür.

Bu nedenle bir regex değişikliği yalnızca tarayıcıyı etkilemez: referans listesini, eksik/gereksiz anahtar kümelerini, JSON tüketicilerini ve CI çıkışını değiştirebilir. Ayrıca yan etki sınırını okuyun: tarayıcı dosya okur; handler seçilen .env dosyasını okur; _output normalde stdout'a, --output verilirse bir rapor dosyasına yazar. Deneyimizde --output kullanmıyoruz ve gerçek .env dosyasını taramıyoruz.

Text
CLI / python -m envdoctor
  -> main(argv)
     -> handle_audit(args)
        -> parse_env_file(selected .env) -> known_keys
        -> audit_codebase(targets, known_keys)
           -> scan_file_for_env_keys(file)
              -> PATTERNS / pat.finditer(line)
              -> list[CodeReference]
           -> referenced, missing, stale sets
        -> JSON report / _output
        -> exit 1 if missing else 0

Okuduğunuz davranışı küçük testlerle sınayın

Bir harita, deneyle sınanmadıkça hâlâ eksik olabilir. Sabitlenen tests/test_auditor.py doğrudan Python/JavaScript erişimlerini ve eksik/gereksiz anahtarları sınar; tests/test_cli.py audit başarı ve eksik anahtar çıkışlarını kontrol eder. Bu iki dosyada dinamik anahtar, alias, çok satırlı erişim ve string içindeki sahte erişim için test görmedim. Bu, deponun bütün testlerinde hiçbir sınır testi olmadığı iddiası değildir.

Aşağıdaki dosyanın her biçimini ayrı bir app.py girdisi olarak sınadım. Amaç kaynak uygulamayı çalıştırmak değil, tarayıcının bu metni nasıl yorumladığını görmek. API_TOKEN ve FAKE_KEY yalnızca deneme isimleri. Dinamik ve alias erişimleri Python açısından geçerli olabilir; tarayıcının onları tanımaması kullanımın yokluğu değildir.

Python
# direct
import os
value = os.getenv("API_TOKEN")

# dynamic
key = "API_TOKEN"
value = os.getenv(key)

# alias
from os import getenv
value = getenv("API_TOKEN")

# multiline
value = os.getenv(
    "API_TOKEN"
)

# string-literal: text, not an environment lookup
text = 'os.getenv("FAKE_KEY")'

Tekrar çalıştırılabilir test ve gerçek çıktısı

Kaynaklar bölümündeki reading-code-contract.py dosyasını envdoctor-reading klasörünün yanına kaydedin. Üst klasörde python reading-code-contract.py ./envdoctor-reading komutunu çalıştırın. Paket kurulumu gerekmez: script doğrudan bu checkout'tan import eder. Python en az 3.12 olmalı; örnek 3.14.7 ile doğrulandı. Script önce dört kaynak dosyasının SHA-256 değerini LF satır sonlarına göre kontrol eder ve farklı sürümde durur.

Test geçici bir klasörde yalnızca API_TOKEN=demo_not_a_secret içeren bir .env oluşturur. Her girdiyi tek dosya tarayıcısı, klasör denetimi ve gerçek main fonksiyonunun JSON/çıkış kodu üzerinden sınar. Deneme dosyaları uygulama olarak çalıştırılmaz; checkout değiştirilmez, ağ bağlantısı kurulmaz ve bytecode yazımı kapatılır. Geçici dosyalar işlem sonunda temizlenir. Aşağıdaki çıktı bu testin gerçek çalıştırmasından alınmıştır.

direct doğru bulunuyor. dynamic, alias ve multiline bulunmuyor; CLI yine 0 dönebiliyor çünkü bulunmuş eksik anahtar yok. string-literal ise gerçek bir getenv çağrısı olmamasına rağmen FAKE_KEY referansı sayılıyor ve çıkış 1 oluyor. Bunlar bu sürümün davranış sınırlarıdır; regex'in bir satır içinde eşleşmesi, ifadenin çalıştırılan kod olduğunu kanıtlamaz.

Test ayrıca node_modules klasörünün klasör taramasında atlandığını, ama o klasördeki bir dosya açıkça hedef verilirse tarandığını doğruladı. Aynı ignore kuralı iki giriş yolunda aynı davranışı üretmiyor. Bu yüzden etki haritasına sadece fonksiyon adını değil, hedefin dosya mı klasör mü olduğunu da yazmak gerekiyor.

Text
{"case": "direct", "detected": ["API_TOKEN"], "missing": [], "exit": 0}
{"case": "dynamic", "detected": [], "missing": [], "exit": 0}
{"case": "alias", "detected": [], "missing": [], "exit": 0}
{"case": "multiline", "detected": [], "missing": [], "exit": 0}
{"case": "string-literal", "detected": ["FAKE_KEY"], "missing": ["FAKE_KEY"], "exit": 1}
PASS: 5 scanner/report/CLI cases and directory-vs-explicit-file boundary

Haritanın sınırlarını ve değişiklik kapsamını yazın

Buradaki test, mevcut davranışı belgeleyen bir karakterizasyon testidir; bütün sonuçları doğru ürün davranışı ilan etmez. String içindeki sahte kullanımı gidermek veya çok satırlı erişimi desteklemek ayrı bir kaynak değişikliği ve yeni beklentiler gerektirir. Bu rehber için EnvDoctor kaynak kodu değiştirilmedi. Bilinen bir hatayı testte korumak, onu kalıcı ürün gereksinimi yapmak değildir.

Metin araması bir başlangıçtır, tam çağrı grafiği değildir. Dinamik import, isim alias'ları, eklenti kayıtları, ortamla seçilen dallar ve kapsam dışındaki tüketiciler ayrıca incelenmelidir. Bu örneğin beş girdisi diğer dillerin bütün erişimlerini, büyük depo performansını veya bütün CLI seçeneklerini doğrulamıyor. Daha büyük bir değişiklikte deponun kendi testlerini ve dış JSON tüketicilerinin sözleşmelerini ayrıca çalıştırın.

İlk değişiklikten önce doldurulacak kısa not

Kendi deponuz için şu notu doldurun: değiştireceğim davranış; sabitlenen sürüm; giriş noktası; doğrudan çağıranlar; veri dönüşümleri; dosya/ağ/yazma yan etkileri; gözlenebilir çıktı; başarısız karşı örnek; kapsamadığım tüketiciler. Her kutuya bütün klasörleri değil, sorunuzla ilgili kanıtı yazın.

EnvDoctor örneğinde değişiklik adayı scan_file_for_env_keys olsa bile kabul ölçütü yalnızca regex eşleşmesi olamaz. CodeReference, missing/stale kümeleri, JSON çıktısı ve çıkış kodunu birlikte değerlendirin. Sonra küçük bir değişiklik yapıp aynı testleri tekrar çalıştırın. Hata ayıklama rehberi deney kurmayı, EnvDoctor kullanım rehberi ise check/sync/audit komutlarının kullanıcı tarafındaki farklarını tamamlıyor.

Kaynak: EnvDoctor: incelenen sabit kaynak sürümü

Kaynak: Giriş noktası ve audit handler

Kaynak: Dosya tarayıcısı ve veri dönüşümleri

Kaynak: Tekrar çalıştırılabilir davranış testi: reading-code-contract.py

Kaynak: ripgrep: resmi arama ve filtreleme rehberi

Kaynak: İlgili rehber: hata ayıklama

Kaynak: İlgili rehber: EnvDoctor kod kullanımını denetlemek

Kaynak: EnvDoctor proje sayfası