2010-11-23 7 views
2

J'aimerais comparer succinctement un arbre de fichiers de configuration, dont la plupart sont plats (c'est-à-dire des paires clé/valeur), mais dont certains sont des scripts XML, bash ou personnalisés. Les informations de configuration sont presque toujours non commandées et peuvent contenir des espaces et des commentaires.Comparaison succincte et fusion partielle des arbres de configuration

Pour les fichiers plats, faire un diff sans espace ou des commentaires sur la sortie triée est très proche de ce que je voudrais faire. Pour XML, il y a sometoolsavailable. Cependant, certains formats personnalisés ont, par exemple, configuration imbriquée. L'ordre des clés n'est pas important, l'ordre des sous-clés n'est pas important, mais l'arborescence est (un peu comme le XML). D'autres sont très dépendants de l'ordre.

Comment vous y prendrez-vous si vous deviez le faire souvent? Y a-t-il des outils assez généraux? Qu'en est-il de ma propre solution? Le nombre de formats n'est ni énorme (certainement pas aussi mauvais que/etc), et la valeur par défaut est plate - peut-être une mise en correspondance de libmagic et de nom de fichier, combinée avec des parseurs personnalisés? Est-ce que quelqu'un a essayé quelque chose comme ça? Une approche consisterait à essayer de résoudre 95% du problème en effectuant un travail décent sur les fichiers avec une structure imbriquée mais non ordonnée et en appliquant un boîtier spécial à quelques autres types d'outils existants. Pouvez-vous suggérer une approche principalement axée sur les travaux pour de simples fichiers imbriqués?

Quelques exemples:

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 

devrait produire

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

ou éventuellement:

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

comme on peut s'y attendre. Cependant, quelque chose comme:

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; 
; 

devrait fonctionner aussi:

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

Répondre

1

Chacun de vos fichiers de configuration a une syntaxe et une sémantique implicite. Il semble que ce que vous voulez faire, est de comparer les fichiers de configuration par la sémantique implicite plutôt que par le texte. La seule façon d'y parvenir est d'avoir un analyseur personnalisé pour chaque type de fichier de configuration. Ensuite, vous devez comparer les fichiers en fonction de la sémantique implicite.

En général, c'est assez difficile à faire, certainement pour les vrais langages de programmation. Nous proposons une solution de compromis, appelez le SmartDifferencers pour analyser le code en fonction de la syntaxe langauge précise, puis comparez-les en fonction des structures linguistiques (expressions, déclarations, déclarations, méthodes, ...), en indiquant les différences comme opérations d'édition abstraites , copier, supprimer, insérer, renommer-identifier dans un bloc). Cela donne succint deltas (ce qui est ce que vous avez demandé) dans des termes qui ont un sens pour les programmeurs, plutôt que de simplement "ce bloc de lignes changé en quelque sorte" typique de diff.

Ces outils connaissent la syntaxe du langage, et ils connaissent un minuscule bit de la sémantique; en particulier, nous essayons (et nous ne sommes pas complètement là pour chacun d'entre eux) de gérer la notion de de éléments de langage commutatifs. En Java, l'ordre des méthodes dans une classe est indifférent. Dans votre cas, l'ordre de certains éléments de configuration est probablement immatériel. Nos machines peuvent en tenir compte. Pour ce faire, vous avez besoin d'un analyseur séparé pour chaque type de fichier de configuration, et de connaissances distinctes pour chaque type de quand vous pouvez mélanger les commandes en toute sécurité. Vous avez besoin d'un outil distinct pour chaque type de fichier de configuration pour le faire correctement. (Ces fichiers qui sont basés sur XML, en effet besoin d'outils separtes parce que vous essayez de distinguer la sémantique ainsi que la syntaxe.). Je pense que votre solution idéale est SmartDifferencers pour chacun de vos types de fichiers de configuration.