Skip to content

Latest commit

 

History

History
281 lines (209 loc) · 7.61 KB

rules.md

File metadata and controls

281 lines (209 loc) · 7.61 KB

Rules

The analyzer rules are a set of instructions that are used to analyze source code and detect issues. Rules are fundamental pieces that codify modernization knowledge.

The analyzer parses user provided rules, evaluates them and generates Violations for matched rules. A collection of one or more rules form a Ruleset. Rulesets provide an opionated way of organizing multiple rules that achieve a common goal. The analyzer CLI takes a set of rulesets as input arguments.

Rule

A Rule is written in YAML. It consists of metadata, conditions and actions. It instructs analyzer to take specified actions when given conditions match.

Rule Metadata

Rule metadata contains general information about a rule:

# id must be unique among a Ruleset
ruleId: "unique_id"
# violations have pre-defined categories
category: "potential|information|mandatory"
# links point to external hyperlinks
# rule authors are expected to provide
# relevant hyperlinks for quick fixes, docs etc
links:
  - url: "konveyor.io"
    title: "title to be shown in report"
# labels are key=value pairs attached to rules, value
# can be empty or omitted, keys can be subdomain prefixed
labels:
  # key=value pair
  - "label1=val1"
  # valid label with value omitted
  - "label2"
  # valid label with empty value
  - "label3="
  # subdomain prefixed key
  - "konveyor.io/label1=val1"
# effort is an integer value to indicate level of 
# effort needed to fix this issue
effort: 1

See labels doc for more details on labels field.

Rule Actions

A rule has message and tag actions.

The message action generates a message for every violation created when rule matches. The message also supports templating in that the custom data exported by providers can be used in the message.

# when a match is found, analyzer generates a violation with this message
message: "helpful message about the violation"

The tag action allows generating tags for the application. Each string in the tag can be a comma separated list of tags. Optionally, tags can have categories.

# when a match is found, analyzer generates these tags for the application
tag:
  # tags can be comma separated
  - "tag1,tag2,tag3"
  # optionally, tags can be assigned categories
  - "Category=tag4,tag5"

Rule Conditions

Finally, a rule contains a when block to specify a condition:

when:
  <condition>
    <nested-condition>

When has exactly one condition. Multiple conditions can be nested within the top-level condition.

Provider Conditions

A "provider" knows how to analyse the source code of a technology. It publishes what it can do with the source code in terms of "capabilities".

A provider condition instructs the analyzer to invoke a specific "provider" and use one of its "capabilities". In general, it is of the form <provider_name>.<capability>:

when:
  <provider>.<capability>: "input"

Analyzer currently supports builtin, java and go providers.

Builtin Provider

builtin is an in-tree provider that can work with vaious different files and internal metadata generated by the engine. It has file, filecontent, xml, json and hasTags capabilities.

file

file capability enables the provider to find files in the source code that match a given pattern:

when:
  builtin.file: "<regex_to_match_filenames>"
filecontent

filecontent capability enables the provider to search for content that matches a given pattern:

when:
  builtin.filecontent: "<regex_to_match_filecontent>"
xml

xml capability enables the provider to query XPath expressions on a list of provided XML files. Unlike providers discussed so far, xml takes two input parameters:

when:
  builtin.xml:
    # xpath must be a valid xpath expression
    xpath: "<xpath_expressions>"
    # filepaths is a list of files to scope xpath query to
    filepaths:
      - "/src/file1.xml"
      - "/src/file2.xml"
json

json capability enables the provider to query XPath expressions on a list of provided JSON files. Unlike xml, currently json only takes xpath as input and performs the search on all json files in the codebase:

when:
  builtin.json:
    # xpath must be a valid xpath expression
    xpath: "<xpath_expressions>"

hasTags

hasTags enables the provider to query application tags. It doesn't deal with the source code, instead it queries the internal data structure to check whether given tags are present for the application:

when:
  # when more than one tags are given, a logical AND is implied
  hasTags:
    - "tag1"
    - "tag2"
Java Provider

Java provider can work with Java source code and provides capabilities referenced and dependency.

referenced

referenced capability enables the provider to find references in the source code. It takes two input parameters:

when:
  java.referenced:
    # regex pattern to match
    pattern: "<pattern>"
    # location defines the exact location where
    # pattern should be matched
    location: CONTRUCTOR_CALL

The supported locations are:

  • CONSTRUCTOR_CALL
  • TYPE
  • INHERITANCE
  • METHOD_CALL
  • ANNOTATION
  • IMPLEMENTS_TYPE
  • ENUM_CONSTANT
  • RETURN_TYPE
  • IMPORT
  • VARIABLE_DECLARATION
Go Provider

Go provider can work with Golang source code and provides capabilities referenced and dependency.

referenced

referenced capability enables the provider to find references in the source code:

when:
  go.referenced: "<regex_to_find_reference>"
dependency

The dependency capability enables the provider to find dependencies for an application:

when:
  go.dependency:
    # name of the dependency to search
    name: "<dependency_name>"
    # upper bound on version of the depedency
    upperbound: "<version_string>"
    # lower bound on version of the dependency
    lowerbound: "<version_string>"

A match is found when the given application has a dependency that falls within the given range of versions.

Logical Conditions

Analyzers provide two basic logical conditions that are useful in making more complex queries by aggregating results of other conditions.

And Condition

The And condition takes an array of conditions and performs a logical "and" operation on their results:

when:
  and:
    - <condition1>
    - <condition2>

Example:

when:
  and:
    - java.dependency:
        name: junit.junit
        upperbound: 4.12.2
        lowerbound: 4.4.0
    - java.dependency:
        name: io.fabric8.kubernetes-client
        lowerbound: 5.0.100

Note that the conditions can also be nested within other conditions:

when:
  and:
  - and:
    - go.referenced: "*CustomResourceDefinition*"
    - java.referenced:
        pattern: "*CustomResourceDefinition*"
  - go.referenced: "*CustomResourceDefinition*"
Or Condition

The Or condition takes an array of other conditions and performs a logical "or" operation on their results:

when:
  or:
    - <condition1>
    - <condition2>

Ruleset

A set of Rules form a Ruleset. Rulesets are an opionated way of passing Rules to Rules Engine.

Each Ruleset is stored in its own directory with a ruleset.yaml file at the directory root that stores metadata of the Ruleset.

# name has to be unique within the provided rulesets
# doesn't necessarily has to be unique globally
name: "Name of the ruleset"
description: "Describes the ruleset"
# additional labels for ruleset
# labels help filter rulesets
labels:
  - awesome_rules1

Rulesets provide a good way of organizing multiple rules that achieve a common goal.