В Часть 1 а также
Часть 2 принадлежащий
В этой серии мы узнали, как создать спецификацию языка и как использовать язык запросов Сильвера для изучения дерева синтаксического анализа наших документов JSON.

Хотя интерактивное исследование кодовой базы с помощью запросов к исходному коду может быть полезным, это не самый практичный способ проверки исходного кода. В этом руководстве мы узнаем, как упаковать запросы, которые мы создали в предыдущей части, в набор правил использовать их как линтер.

Если вы уже установили sylver а также sylver --version не выводит
номер версии >= 0.1.4пожалуйста, перейдите к загрузить новую копию программного обеспечения.


Прелюдия

Мы повторно используем два файла из последнего урока:

node JsonNode { }

node Null: JsonNode { }

node Bool: JsonNode { }

node Number: JsonNode { }

node String: JsonNode { }

node Array: JsonNode { 
    elems: List<JsonNode> 
}

node Object: JsonNode {
    members: List<Member>
}

node Member: JsonNode {
    key: String,
    value: JsonNode
}

term COMMA = ','
term COLON = ':'
term L_BRACE = '{'
term R_BRACE = '}'
term L_BRACKET = '['
term R_BRACKET = ']'
term NULL = 'null'

term BOOL_LIT = `true|false`
term NUMBER_LIT = `\-?(0|([1-9][0-9]*))(.[0-9]+)?((e|E)(\+|-)?[0-9]+)?`
term STRING_LIT = `"([^"\\]|(\\[\\/bnfrt"])|(\\u[a-fA-F0-9]{4}))*"`


ignore term WHITESPACE = `\s`

rule string = String { STRING_LIT }

rule member = Member { key@string COLON value@main }

rule main =
    Null { NULL }
  | Number { NUMBER_LIT }
  | Bool { BOOL_LIT }
  | string
  | Array { L_BRACKET elems@sepBy(COMMA, main) R_BRACKET }
  | Object { L_BRACE members@sepBy(COMMA, member) R_BRACE }@
Войти в полноэкранный режим

Выйти из полноэкранного режима

{
    "variables": [
        {
            "name": "date of birt`",
            "description": "Customer's date of birth",
            "type": "datetime"
        },
        {
            "name": "activity",
            "description": "A short text describing the customer's profession",
            "type": "string"
        },
        {
            "name": "country",
            "description": "Customer's country of residence",
            "type": "string",
            "values": ["us", "fr", "it" ]
        }
    ]
}

Войти в полноэкранный режим

Выйти из полноэкранного режима


Выход из REPL


Создание набора правил

Упаковать правила из предыдущего руководства в повторно используемый набор правил так же просто, как
создание следующего YAML файл:

id: 'JSON ruleset'
language: json.syl

rules: 
  - id: variable_length
    message: Variable name is too long
    severity: warning
    query: >
      match String desc when desc.text.length > 37 && desc.parent is {
        Member m when m.key.text == '"description"'
      }  

  - id: variable_format 
    message: Variable name isn't a lowercase word
    severity: info
    query: >
      match String s when !s.text.matches(`"[a-z]+"`) && s.parent is {
        Member m when m.key.text == '"name"'
      }    

  - id: types_or_values
    message: Fields 'type' and 'values' are mutually exclusive    
    severity: error
    note: The type can be deduced from the values list.
    query: >
      match Object n when
        any n.members.children match {  
            Member m when m.key.text == '"type"' 
        }
        && any n.members.children match { 
            Member m when m.key.text == '"values"' 
        }
Войти в полноэкранный режим

Выйти из полноэкранного режима

Где id представляет собой удобочитаемое описание набора правил, и language относится к
файл спецификации языка.

Следующие свойства описывают отдельные правила, составляющие набор правил:

  • id: уникальное и короткое имя правила
  • сообщение: краткое описание проблемы
  • серьезность: ошибка, информация или предупреждение
  • запрос: встроенный запрос
  • примечание: необязательная дополнительная информация

Предполагая, что наш файл набора правил называется ruleset.yamlмы можем запускать этот набор правил на каждом .json файл в текущем каталоге, вызвав следующую команду:

sylver ruleset run --files "*.json" --rulesets ruleset.yaml
Войти в полноэкранный режим

Выйти из полноэкранного режима


Хранение конфигурации нашего проекта

Если мы хотим проверить нашу кодовую базу на соответствие нескольким наборам правил, повторив приведенное выше
Команда для каждого набора правил может быть утомительной. Вместо этого мы можем написать конфигурацию проекта
в sylver.yaml файл в корне нашего проекта:

subprojects:
  - language: json.syl
    rulesets: ['ruleset.yaml']
    include:
      - './**/*.json'
Войти в полноэкранный режим

Выйти из полноэкранного режима

Конфигурация содержит список подпроектов, каждый из которых имеет свой язык, необязательный список наборов правил и список файлов для включения.

Вызов sylver check будет читать конфиг из sylver.yaml и запустить
указанные наборы правил.


Git-интеграция

Если вы хотите повторно использовать свои языковые спецификации или наборы правил в нескольких проектах, скопируйте .syl а также .yaml файлов в каждом проекте было бы неудобно. К счастью
наборы правил и конфигурации проекта могут ссылаться на артефакты, хранящиеся в репозитории git.

Спецификация языка и набор правил для этого руководства были загружены на это репотак что если мы перепишем наш sylver.yaml файл конфигурации как:

subprojects:
  - language: 
      repo: 
      file: json.syl
    rulesets: 
      - repo: 
        file: 'ruleset.yaml'
    include:
      - './**/*.json'
Войти в полноэкранный режим

Выйти из полноэкранного режима

спецификация языка и набор правил будут автоматически скопированы в .sylver каталог
при беге sylver check.

Теперь у нас есть повторно используемый линтер для наших файлов конфигурации JSON, созданный из
поцарапать, используя DSL Сильвера.

В следующем руководстве будет использоваться предварительно созданный Голанг написать универсальный линтер Go.