Я хотел бы кратко различать дерево файлов конфигурации, большинство из которых являются плоскими (то есть пары ключ / значение), но некоторые из которых являются XML, скриптами bash или пользовательскими форматами. Информация о конфигурации почти всегда не упорядочена и может содержать пробелы и комментарии.
Для плоских файлов выполнение различий без пробелов или комментариев к отсортированному выводу очень близко к тому, что я хотел бы сделать. Для XML есть некоторые инструменты доступные . Однако некоторые пользовательские форматы имеют, например, вложенная конфигурация Порядок ключей не важен, порядок подразделов не важен, но древовидная структура (очень похожа на XML). Другие очень зависят от заказа.
Как бы вы поступили так, если бы вам приходилось делать это часто? Есть ли какие-либо инструменты, которые являются достаточно общими? А как насчет моего собственного решения? Количество форматов не так уж и велико (конечно, не так плохо, как / etc), а значение по умолчанию плоское - возможно, какое-то соответствие libmagic и имени файла в сочетании с пользовательскими парсерами? Кто-нибудь пробовал что-то подобное?
Один из подходов состоит в том, чтобы попытаться решить 95% проблемы, выполнив приличную работу с файлами с вложенной, но неупорядоченной структурой и со специальным корпусом нескольких других типов с помощью существующих инструментов. Можете ли вы предложить подход к простым вложенным файлам, в основном работающий?
Некоторые примеры:
com.example.resource.host=foo
com.example.resource.port=8080
против
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;
;
против
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;
> ;