2010-11-23 69 views
2

我想簡要地比較一下配置文件的樹,其中大部分是扁平的(即鍵/值對),但其中一些是XML,bash腳本或自定義格式。配置信息幾乎總是沒有排序,並且可以包含空白和註釋。簡單地比較和部分合並配置樹

對於平面文件,在沒有空格的情況下執行差異操作或對已排序的輸出進行註釋非常接近我想要做的事情。對於XML,有sometoolsavailable。然而一些自定義格式例如嵌套配置。鍵的順序並不重要,子鍵的順序並不重要,但樹結構(很像XML)。其他則非常依賴訂單。

如果你經常這樣做,你會怎麼做呢?那裏有足夠一般的工具嗎?怎麼樣滾動我自己的解決方案?格式的數量也不是很大(當然不會像/ etc一樣糟糕),並且默認是平坦的 - 可能是一些libmagic和文件名匹配,並結合自定義分析器?有沒有人試過類似的東西?

一種方法是嘗試通過對嵌套但無序結構的文件進行體面的工作來解決95%的問題,並使用現有工具特殊套用一些其他類型的文件。你能建議一個主要的工作方法來簡單的嵌套文件?

一些例子:

com.example.resource.host=foo 
com.example.resource.port=8080 

VS

com.example.resource.port=8080 
com.example.resource.host=bar 
//com.example.network.timeout=600 
com.example.network.timeout=300 

應該產生

< com.example.resource.host=foo 
--- 
> com.example.resource.host=bar 
> //com.example.network.timeout=600 
> com.example.network.timeout=300 

或任選:

< com.example.resource.host=foo 
--- 
> com.example.resource.host=bar 
> com.example.network.timeout=300 

如您所料。然而,這樣的:

Conf com.example.resource = 
    Conf host = foo; 
    Conf port = 8080; 
; 

VS

Conf com.example.resource = 
    Conf port = 8080; 
    Conf host = bar; 
; 
Conf com.example.network = 
    Conf timeout = 300; 
; 

也應努力:

<  Conf host = foo 
--- 
>  Conf host = bar 
> Conf com.example.network = 
>  Conf timeout = 300; 
> ; 

回答

1

每個配置文件中有語法和語義隱含。看起來你想要做的是通過隱含的語義而不是文本比較配置文件。

要做到這一點的唯一方法是爲每個配置文件類型定製解析器。然後你需要根據隱含的語義來比較文件。

一般來說,這對於真正的編程語言來說確實很難做到。我們提供了一個折中的解決方案,請撥打SmartDifferencers,根據精確的語言語法解析代碼,然後根據語言結構(例如表達式,語句,聲明,方法等)進行比較,將差異報告爲抽象編輯操作,複製,刪除,插入,塊內的重命名標識符)。這給了succint deltas(這就是你所要求的),這對程序員來說是有意義的,而不僅僅是「這一行代碼塊以某種方式改變了」,這是典型的diff。

這些工具知道語言的語法,他們知道微小的位的語義;特別是,我們嘗試(並且我們並非完全針對它們)來處理交換語言元素的概念 。在Java中,類中方法的順序並不重要。在你的情況下,一些配置元素的順序可能不重要。我們的機器可以考慮到這一點。

要做到這一點想要做什麼,您需要爲每種類型的配置文件分別解析器,併爲每種類型的安全分配命令時分別瞭解。對於每種類型的配置文件,您都需要一個單獨的工具來執行此操作。 (那些基於XML的文件實際上需要separtes工具,因爲您試圖區分語義和語法。)。我認爲您的理想解決方案是針對每種配置文件類型的SmartDifferencers。