İki YAML dosyasını girinti derdine düşmeden karşılaştırma
İki YAML dosyasını karşılaştırmanın en hızlı yolu, ikisini yan yana bir diff aracına yapıştırmak, girintiyi normalleştirmek ve vurguladığı satırları okumaktır. Karşılaştırma kolay kısımdır. YAML'de gürültü her zamankinden daha sinsidir: yanlış yere düşmüş bir sekme, yeniden sıralanmış bir anahtar veya birinin tırnak içine aldığı bir değer, aynı veriye yüklenen iki dosyayı hiç ortak yanları yokmuş gibi gösterebilir.
Bu rehber, temiz ve güvenilir bir YAML diff'i nasıl alacağınızı anlatır. İki eşdeğer dosyanın kâğıt üzerinde neden ayrıştığına, bilmeye değer yöntemlere ve takip edebileceğiniz çalışılmış bir örneğe bakacağız. Yalnızca aracı istiyorsanız, YAML karşılaştırma sayfamız bunların tümünü tarayıcıda yapar.
YAML dosyaları neden aldatıcı şekilde karşılaştırması zordur
YAML boşluğa duyarlı bir biçimdir (bkz. YAML 1.2.2 belirtimi), ve diff'leri çetrefilli yapan tam da budur. Girinti anlam taşır, ama girintinin miktarı taşımaz, yeterince tutarlı olduğu sürece. Yani iki boşlukla girintilenmiş bir dosya ile dört boşlukla girintilenmiş bir başkası aynı yapıya yüklenirken, bir metin diff'ine her satır farklı görünebilir.
Aklınızda tutmanız gereken anahtar gerçek şu: bir YAML mapping'i anahtar/değer çiftleri kümesidir ve JSON nesneleri gibi, o anahtarların sırası veriyi değiştirmez. Yani bu:
name: Ada Lovelace
role: editor
ve bu:
role: editor
name: Ada Lovelace
bir satır diff'i onları kırmızı ve yeşile boyasa da aynı mapping'e yüklenir. Bir sequence'in öğeleri ise sıralıdır, dolayısıyla bir listeyi yeniden sıralamak gerçek bir değişikliktir.
| Diff'te gördüğünüz | Gerçek bir değişiklik mi? | Ne yapmalı |
|---|---|---|
| 2 boşluk vs 4 boşluk girinti | Hayır, yalnızca tutarlılık önemlidir | İkisini de aynı genişliğe yeniden biçimlendirin |
| Mapping anahtarları farklı sırada | Hayır, mapping'ler sırasızdır | Her iki tarafta anahtarları sıralayın |
true vs "true" | Evet, boolean vs dize | Araştırın, bu gerçek |
name: Ada vs name: "Ada" | Hayır, aynı dize değeri | Tırnakları normalleştirin |
Flow stili [a, b] vs blok liste | Hayır, aynı sequence | İkisi için tek bir stil seçin |
| Sequence öğeleri farklı sırada | Evet, sequence'ler sıralıdır | Araştırın, bu gerçek |
Oradaki iki satır gerçek tuzaktır. Tırnaksız true bir boolean'dır;
tırnaklı haldeyse "true" dizesidir ve bu ayrım gerçek kesintilere yol açmıştır. Ama
name: Ada ile name: "Ada" aynı dizedir. Bir ayrıştırıcının
bunu nasıl çözdüğünün ince ayrıntısını isterseniz, belirtimin
core schema
bölümü başvuru kaynağıdır.
YAML'yi karşılaştırmanın dört yolu ve her birine ne zaman başvurulur
Tek bir en iyi yöntem yoktur. Dosyaların nerede olduğuna ve neyi öğrenmek istediğinize bağlıdır. Yaygın seçenekler şöyle kıyaslanır.
| Yöntem | En iyisi | Çaba | YAML'yi anlıyor mu? |
|---|---|---|---|
| Gözle kontrol | Çok küçük dosyalar, bir veya iki anahtar | Düşük | Hayır, ayrıştırıcı sizsiniz |
| Çevrimiçi diff aracı | Hızlı kontroller, her yerden yapıştırma | Düşük | Yeniden biçimlendirmeyle, evet |
Komut satırı (yq) | Diskteki dosyalar, betikleme, anahtar sıralama | Orta | Evet, önce sıralarsanız |
IDE veya git diff | Zaten bir depoda olan dosyalar | Commit edilmişse düşük | Varsayılan olarak satır tabanlı |
Çoğu kişi için bir tarayıcı aracı hızda kazanır: kurulacak hiçbir şey yoktur ve bir parçayı doğrudan bir Kubernetes manifestinden veya bir CI yapılandırmasından yapıştırabilirsiniz. Pürüz, biçimlendirme gürültüsüdür, onu sonra ele alacağız. Terminalde yaşıyorsanız, yq öğrenilecek araçtır ve jq'nun JSON için yaptığı gibi anahtarları sıralayabilir.
En hızlı temiz karşılaştırma, adım adım
Biri bana iki manifest uzatıp "ne farklı?" diye sorduğunda kullandığım rutin budur. Yaklaşık on beş saniye sürer.
- YAML karşılaştırma aracını açın.
- Orijinali sola, yeni sürümü sağa yapıştırın.
- Aynı girintiyi paylaşsınlar diye her iki tarafta Biçimlendir'e tıklayın.
- Yeniden sıralanmış mapping anahtarları değişiklik olarak görünmeyi bıraksın diye anahtarları sırala'yı açın.
- Sonucu okuyun. Yeşil eklenen, kırmızı kaldırılandır ve değişen bir değer her renkten biri olarak görünür.
Üç ve dördüncü adımlar işin tüm püf noktasıdır. Her iki dosya aynı girintiyi kullanıp anahtarları sıralandığında, vurgulanacak tek şey gerçekte ne değiştiğidir. Diff motorumuz Google'ın diff-match-patch üzerine kuruludur; önce satır satır karşılaştırır, böylece uzun dosyalarda bile hızlı kalır.
Çalışılmış bir örnek
Diyelim ki bir kullanıcı kaydındaki bir değişikliği inceliyorsunuz. İşte öncesi:
name: Ada Lovelace
role: editor
active: true
seats: 3
Ve işte bir takım arkadaşının size verdiği hâliyle sonrası:
active: true
name: Ada Lovelace
role: admin
seats: 5
team: platform
Bunları ham bir satır diff'ine atın; anahtarlar farklı sırada olduğu için neredeyse her satır yer değiştirmiş gibi görünür. İkisini de yeniden biçimlendirip sıralayın, gerçek hikâye kısadır:
| Anahtar | Önce | Sonra | Değişiklik |
|---|---|---|---|
role | editor | admin | Değiştirildi |
seats | 3 | 5 | Değiştirildi |
team | — | platform | Eklendi |
name | Ada Lovelace | Ada Lovelace | Değişiklik yok |
active | true | true | Değişiklik yok (yalnızca taşındı) |
Üç gerçek düzenleme: bir rol yükseltmesi, bir koltuk sayısı ve yeni bir team
anahtarı. Yeniden sıralama gürültüydü. editor'dan admin'e
o terfi, incelemede yakalamak isteyeceğiniz türden bir şeydir ve yanlış pozitiflerin
altına gömüldüğünde kaçırması kolaydır.
Komut satırında biçimlendirme gürültüsünü yok etmek
Dosyalarınız zaten diskteyse, aynı "yeniden biçimlendir ve sırala" fikri iki kısa
komutla işler. yq anahtarları sıralayıp kanonik bir biçim yeniden
üretebilir, böylece sonrasında düz bir diff dürüst olur:
yq -P 'sort_keys(..)' old.yaml > old.sorted.yaml
yq -P 'sort_keys(..)' new.yaml > new.sorted.yaml
diff old.sorted.yaml new.sorted.yaml
Artık diff yalnızca gerçekten değişen değerleri raporlar, çünkü her iki
dosya da aynı girintiye ve aynı anahtar sırasına sahiptir. Bu, tarayıcıda
Biçimlendir'e ve anahtarları sırala'ya tıklamanın terminal karşılığıdır.
YAML'ye özgü tuzaklar
Birkaç YAML özelliği insanları şaşırtan diff'lere yol açar. Anchors ve aliases
(&name ve *name) bir dosyanın bir değeri referansla
tekrarlamasına izin verirken başka bir dosya onu tam olarak yazar; ikisi de aynı
veriye yüklenir ama tamamen farklı okunur. Meşhur "Norveç sorunu" bir başkasıdır:
tırnaksız no, off ve yes eski YAML 1.1
ayrıştırıcılarında boolean olarak çözümlenebilir, dolayısıyla country: NO
false olabilir. YAML 1.2 şemayı düzeltti, ama birçok araç hâlâ 1.1
davranışını taşır. Bir değer tür değiştirmiş gibi göründüğünde, ilk kontrol edilecek
şey budur.
Dikkat edilecek yaygın çukurlar
| Çukur | Neden ısırır | Çözüm |
|---|---|---|
| Girinti için sekmeler | YAML girinti için sekmeleri yasaklar; dosya ayrıştırılmayabilir bile | Önce sekmeleri boşluğa dönüştürün |
| Tırnaklı vs tırnaksız skalerler | "true" bir dizedir, true bir boolean'dır | Bu gerçek bir değişiklik olabilir, göz ardı etmeyin |
| Anchors ve aliases | Bir dosya değeri satır içine koyar, diğeri ona referans verir | Anchors'ı çözün, sonra genişletilmiş biçimi karşılaştırın |
| Norveç sorunu | no, YAML 1.1'de false olarak çözümlenebilir | Belirsiz dizeleri tırnağa alın; ayrıştırıcı sürümünüzü kontrol edin |
| Satır sonu boşluğu | Bir değerden sonraki görünmez boşluklar değişiklik olarak görünür | Karşılaştırmadan önce satır sonu boşluğunu kırpın |
YAML ve JSON göründüklerinden daha yakındır
Her JSON belgesi geçerli YAML'dir, çünkü YAML 1.2 JSON'un bir üst kümesidir. Karşılaştırma için bu kullanışlıdır: girinti veya anchors size zorluk çıkarıyorsa, her iki dosyayı JSON'a dönüştürün, aynı şekilde biçimlendirin ve onun diff'ini alın. PyYAML dâhil birçok ayrıştırıcı, YAML'yi JSON olarak yeniden üretebileceğiniz düz bir veri yapısına gidip getirir; bu da biçemsel farkları soyup yalnızca veriyi bırakır.
İlgili araçlar
YAML nadiren tek başına gelir. Aynı verinin JSON biçimini karşılaştırıyorsanız,
JSON karşılaştırma aynı fikri uygular. Ortam
ayarları ve .env dosyaları
yapılandırma karşılaştırma sayfasında güzel
hizalanır ve iki API çağrısı arasındaki değişiklikleri incelemek
API yanıt diff'inin yapıldığı şeydir.
Sık sorulan sorular
- YAML dosyalarını çevrimiçi karşılaştırmak onları bir yere yükler mi?
- comparetext.org'da diff tarayıcınızda çalışır. İki YAML dosyası kendi makinenizde JavaScript tarafından karşılaştırılır, dolayısıyla Kaydet veya Paylaş'a açıkça tıklamadığınız sürece bir sunucuya hiçbir şey gönderilmez. Bu, Kubernetes manifestleri, CI yapılandırmaları ve her tuş vuruşunda yükleyen bir siteye yapıştırmak istemeyeceğiniz diğer veriler için onu güvenli kılar.
- İki YAML dosyam neden her satırı farklı gösteriyor?
- Neredeyse her zaman biçimlendirmedir, gerçek değişiklik değil. Bir dosya iki boşlukla, diğeri dörtle girintilenmiştir, ya da mapping anahtarları farklı sıradadır, ya da biri tırnak kullanır diğeri kullanmaz. Her iki tarafı aynı girintiye yeniden biçimlendirin ve sıra önemini yitirsin diye anahtarları sıralayın. Bundan sonra diff genellikle gerçekten değişen birkaç değere küçülür.
- YAML karşılaştırırken girinti genişliği önemli mi?
- Anlam için değil, yalnızca tutarlılık için. YAML yapıyı göstermek için girinti kullanır, ama her seviye dosya içinde tutarlı olduğu sürece iki ya da dört boşluk kullanmanızı umursamaz. Yani iki boşluklu bir dosya ile dört boşluklu bir dosya aynı veriyi tutarken bir metin diff'ine tamamen farklı görünebilir. İkisini de aynı genişliğe yeniden biçimlendirmek o yanlış farkı kaldırır. Sekmeler ise girinti için hiç izinli değildir.
- Anahtar sırasını yok sayarak YAML'yi nasıl karşılaştırırım?
- YAML mapping anahtarları sırasızdır, dolayısıyla aynı anahtarları farklı sırada içeren iki dosya aynı veriyi tutar. Bir metin diff'inin de buna katılması için, karşılaştırmadan önce her iki tarafta anahtarları sıralayın. Tarayıcıda anahtarları sırala (kanonikleştir) seçeneğini kullanın. Komut satırında yq bunu sort_keys ile yapar. Her iki dosyanın anahtarları aynı sıralı düzene girdiğinde, yalnızca gerçek değer değişiklikleri görünür. Sequence öğeleri sıralı kalır, dolayısıyla onları sıralamayın.
- YAML'de Norveç sorunu nedir?
- Tırnaksız NO değerinin "NO" dizesi yerine boolean false olarak çözümlenip Norveç ülke kodunun false olduğu klasik bir YAML tuzağıdır. Bu, yes, no, on ve off'u boolean olarak ele alan YAML 1.1 ayrıştırıcılarında olur. YAML 1.2 kuralları daralttı, ama birçok araç hâlâ 1.1 davranışını taşır. Diff'inizde bir değer bir sözcükten true ya da false'a dönmüş gibi görünüyorsa, tırnaksız boolean benzeri bir dize olası nedendir. Değeri tırnağa almak sorunu giderir.
- Sayfa donmadan büyük YAML dosyalarını karşılaştırabilir miyim?
- Evet, belli bir noktaya kadar. Satır modu diff, her karakter yerine önce tüm satırları karşılaştırdığı için binlerce satırlık dosyalarda hızlı kalır. Çok büyük dosyalar (birkaç megabayt) veriyi akıtan yq veya git diff gibi bir komut satırı aracıyla daha iyi ele alınır. Bir tarayıcıda rahatça kaydırabileceğiniz her şey için çevrimiçi bir diff daha hızlı seçenektir.
Denemeye hazır mısınız? Dosyalarınızı YAML karşılaştırma aracına yapıştırın ve neyin değiştiğini görün.