Язык Terraform не является обычным языком , и поэтому не существует полностью общего способа обрабатывать его с помощью регулярных выражений.
Однако язык имеет некоторые ограничения по синтаксису блока это означает, что вы можете написать «достаточно хороший» heuristi c, который будет работать в большинстве случаев (но все же не во всех). Вот несколько полезных фактов о языке Terraform, которые могут немного помочь решить проблему:
Открытие блока всегда должно появляться на одной строке, включая открывающую фигурную скобку. Недопустимо добавлять дополнительные символы новой строки между ключевым словом module
и скобкой {
.
Существует два способа записи блока:
- Обычный макет для заголовка должен быть на отдельной строке, заканчивающейся открывающей скобкой, которая вводит тело блока:
{
. - Компактный однострочный макет имеет весь блок на одной строке, с одним аргументом внутри, например
module "foo" { source = "./bar" }
.
Закрывающая фигурная скобка для блока в обычном макете всегда находится на отдельной строке.
Конечно, есть и не очень удобные факты:
Terraform также использует фигурные скобки для выражений своего конструктора объектов, поэтому наивная охота на открывающие и закрывающие фигурные скобки найти как границы блока, так и границы конструктора объекта.
Синтаксис шаблона строки использует ${
или %{
в качестве открывающих разделителей, но использует }
в качестве закрывающих разделителей, добавляя третье значение слова osing brace.
Синтаксис "heredo c" выходит за рамки обычных правил синтаксического анализа и означает, что может появиться произвольное количество фигурных скобок (которые не должны быть сбалансированы). Но они всегда начинаются с <<
или <<-
, за которым следует идентификатор в конце строки, а затем заканчиваются тем же идентификатором в собственной строке.
С все это говорит, что если у вас есть контроль над вводом и вы можете гарантировать, что он не будет включать «крайние случаи», такие как комментарии, в середине заголовков блоков, heredo c последовательностей, содержащих то, что выглядит как блок модуля, et c затем Вы можете получить «достаточно хороший» результат, построчно обрабатывая входные данные:
- Пусть B = 0
- Для каждой строки во входных данных :
- Если B равно нулю:
- Если строка соответствует
^module ["\w- ]*{
, тогда выполнить любое действие, которое вы хотите предпринять для блока модуля. - Для каждого символа в строке :
- Если символ
{
, то приращение B - Если символ
}
, тогда декремент B
Используется наивный Брейс-счет подход к приближенному нахождению границ блоков. Он потерпит неудачу, если вход содержит буквенную строку (либо в кавычках, либо в heredo c) с несбалансированными фигурными скобками внутри него, так что вы можете попытаться улучшить ее, посчитав пары открывающих / закрывающих кавычек и heredo c.
У всего, кроме полного синтаксического анализатора для языка, всегда будет некоторый крайний случай, который он не может обработать, но если вы можете ограничить свой ввод, чтобы он не включал в себя ситуации, которые ваш простой набор правил не может понять, тогда такой подход, как Выше может работать для вас.
Если вы захотите написать свою программу в Go, то вы сможете использовать пакет hclwrite
, который является частью базовой библиотеки, которую Terraform использует для реализации своего синтаксиса языка. Он имеет полный синтаксический анализатор и позволяет вносить «хирургические» изменения в то, что он читает, хотя в то время, когда я пишу это, у него, похоже, нет функций для добавления комментариев к блокам, в частности, так что в настоящее время он не готов к решению вашей спецификации c цель здесь.
Может оказаться полезным для тех, кто найдет этот вопрос в будущем, у которых есть другие цели, связанные с изменением существующих конфигураций Terraform, и он может получить дополнительные функциональные возможности для поддержки других вариантов использования в будущем.