Chapter 2. Creating YAML rules
Chapter 2. Creating YAML rules Each analyzer rule is a set of instructions that are used to analyze source code and detect issues that are problematic for migration. The analyzer parses user-provided rules, applies them to applications' source code, and generates issues for matched rules. A collection of one or more rules forms a ruleset. Creating rulesets provides a way of organizing multiple rules that achieve a common goal. The analyzer CLI takes rulesets as input arguments. 2.1. YAML rule structure and syntax MTA rules are written in YAML. Each rule consists of metadata, conditions and actions, which instruct the analyzer to take specified actions when given conditions match. A YAML rule file in MTA contains one or more YAML rules. 2.1.1. Rule metadata Rule metadata contains general information about the rule. The structure of metadata is as follows: ruleId: "unique_id" 1 labels: 2 # 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: 1 3 category: mandatory 4 1 The ID must be unique within the ruleset to which the rule belongs. 2 See below for a description of the label format. 3 effort is an integer value that indicates the level of effort needed to fix this issue. 4 category describes the severity of the issue for migration. The value can be either mandatory , optional or potential . For a description of these categories, see Rule categories . 2.1.1.1. Rule labels Labels are key=val pairs specified for rules or rulesets as well as dependencies. For dependencies, a provider adds the labels to the dependencies when retrieving them. Labels on a ruleset are automatically inherited by all the rules that belong to it. Label format Labels are specified under the labels field as a list of strings in key=val format as follows: labels: - "key1=val1" - "key2=val2" The key of a label can be subdomain-prefixed: labels: - "konveyor.io/key1=val1" The value of a label can be empty: labels: - "konveyor.io/key=" The value of a label can be omitted. In that case, it is treated as an empty value: labels: - "konveyor.io/key" Reserved labels The analyzer defines some labels that have special meaning as follows: konveyor.io/source : Identifies the source technology to which a rule or a ruleset applies konveyor.io/target : Identifies the target technology to which a rule or a ruleset applies Label selector The analyzer CLI takes the --label-selector field as an option. It is a string expression that supports logical AND, OR and NOT operations. You can use it to filter-in or filter-out rules by their labels. Examples: To filter-in all rules that have a label with the key konveyor.io/source and value eap6 : --label-selector="konveyor.io/source=eap6" To filter-in all rules that have a label with the key konveyor.io/source and any value: --label-selector="konveyor.io/source" To perform logical AND operations on matches of multiple rules using the && operator: --label-selector="key1=val1 && key2" To perform logical OR operations on matches of multiple rules using the || operator: --label-selector="key1=val1 || key2" To perform a NOT operation to filter-out rules that have key1=val1 label set using the ! operator: --label-selector="!key1=val1" To group sub-expressions and control precedence using AND: --label-selector="(key1=val1 || key2=val2) && !val3" Dependency labels The analyzer engine adds labels to dependencies. These labels provide additional information about a dependency, such as its programming language and whether the dependency is open source or internal. Currently, the analyzer adds the following labels to dependencies: labels: - konveyor.io/dep-source=internal - konveyor.io/language=java Dependency label selector The analyzer CLI accepts the --dep-label-selector option, which allows filtering-in or filtering-out incidents generated from a dependency by their labels. For example, the analyzer adds a konveyor.io/dep-source label to dependencies with a value that indicates whether the dependency is a known open source dependency. To exclude incidents for all such open source dependencies, you can use --dep-label-selector as follows: konveyor-analyzer ... --dep-label-selector !konveyor.io/dep-source=open-source The Java provider in the analyzer can also add an exclude label to a list of packages. To exclude all such packages, you can use --dep-label-selector and the ! operator as follows: konveyor-analyzer ... --dep-label-selector !konveyor.io/exclude 2.1.1.2. Rule categories mandatory You must resolve the issue for a successful migration, otherwise, the resulting application is not expected to build or run successfully. An example of such an issue is proprietary APIs that are not supported on the target platform. optional If you do not resolve the issue, the application is expected to work, but the results might not be optimal. If you do not make the change at the time of migration, you need to put it on the schedule soon after your migration is completed. An example of such an issue is EJB 2.x code not upgraded to EJB 3. potential You need to examine the issue during the migration process, but there is not enough information to determine whether resolving the issue is mandatory for the migration to succeed. An example of such an issue is migrating a third-party proprietary type when there is no directly compatible type on the target platform. 2.1.1.3. Rule Actions Rules can include 2 types of actions: message and tag . Each rule includes one of them or both. Message actions A message action creates an issue with a message when the rule matches. The custom data exported by providers can also be used in the message. message: "helpful message about the issue" Example: - ruleID: test-rule when: <CONDITION> message: Test rule matched. Please resolve this migration issue. Optionally, a message can include hyperlinks to external URLs that provide relevant information about the issue or a quick fix. links: - url: "konveyor.io" title: "Short title for the link" A message can also be a template to include information about the match interpolated through custom variables on the rule. Tag actions A tag action instructs the analyzer to generate one or more tags for the application when a match is found. Each string in the tag field can be a comma-separated list of tags. Optionally, you can assign categories to tags. tag: - "tag1,tag2,tag3" - "Category=tag4,tag5" Example - ruleID: test-rule when: <CONDITION> tag: - Language=Golang - Env=production - Source Code A tag can be a string or a key=val pair, where the key is treated as a tag category in MTA. Any rule that has a tag action is referred to as a "tagging rule" in this document. Note that issues are not created for rules that contain only tag actions. 2.1.1.4. Rule conditions Each rule has a when block, which specifies a condition that needs to be met for MTA to perform a certain action. The when block contains one condition, but that condition can have multiple conditions nested under it. when: <condition> <nested-condition> MTA supports three types of conditions: provider , and , and or . 2.1.1.4.1. Provider conditions The Application Analyzer detects the programming languages, frameworks, and tools used to build an application, and it generates default rulesets for each supported provider using the Language Server Protocol (LSP) accordingly. Each supported provider has a ruleset defined by default and is run independently in a separate container. MTA supports multi-language source code analysis. Searching for a specific language in the source code is enabled using the provider condition. This condition defines a search query for a specific language provider. The provider condition also specifies which of the provider's "capabilities" to use for analyzing the code. The provider condition has the form <provider_name>.<capability> : when: <provider_name>.<capability> <input_fields> The analyzer currently supports the following provider conditions: builtin java go dotnet Important Support for providing a single report when analyzing multiple applications on the CLI is a Technology Preview feature only. Technology Preview features are not supported with Red Hat production service level agreements (SLAs) and might not be functionally complete. Red Hat does not recommend using them in production. These features provide early access to upcoming product features, enabling customers to test functionality and provide feedback during the development process. For more information about the support scope of Red Hat Technology Preview features, see Technology Preview Features Support Scope . Provider rule conditions Provider name Providers that are fully supported and included in the product Java Providers that have rules already defined in the product .NET Providers that require custom rulesets for analysis Go Python Node.js 2.1.1.4.1.1. builtin provider builtin is an internal provider that can analyze various files and internal metadata generated by the engine. This provider has the following capabilities: file filecontent xml json hasTags file The file capability enables the provider to search for files in the source code that match a given pattern. when: builtin.file: pattern: "<regex_to_match_filenames>" filecontent The filecontent capability enables the provider to search for content that matches a given pattern. when: builtin.filecontent: filePattern: "<regex_to_match_filenames_to_scope_search>" pattern: "<regex_to_match_content_in_the_matching_files>" xml The xml capability enables the provider to query XPath expressions on a list of provided XML files. This capability takes 2 input parameters, xpath and filepaths . when: builtin.xml: xpath: "<xpath_expressions>" 1 filepaths: 2 - "/src/file1.xml" - "/src/file2.xml" 1 xpath must be a valid XPath expression. 2 filepaths is a list of files to apply the XPath query to. json The json capability enables the provider to query XPath expressions on a list of provided JSON files. Currently, json only takes XPath as input and performs the search on all JSON files in the codebase. when: builtin.json: xpath: "<xpath_expressions>" 1 1 xpath must be a valid XPath expression. hasTags The hasTags capability enables the provider to query application tags. It queries the internal data structure to check whether the application has the given tags. when: # when more than one tag is given, a logical AND is implied hasTags: 1 - "tag1" - "tag2" 1 When more than one tag is given, a logical AND is implied. 2.1.1.4.1.2. java provider The java provider analyzes Java source code. This provider has the following capabilities: referenced dependency referenced The referenced capability enables the provider to find references in the source code. This capability takes three input parameters: pattern , location , and annotated . when: java.referenced: pattern: "<pattern>" 1 location: "<location>" 2 annotated: "<annotated>" 3 1 A regular expression pattern to match, for example, org.kubernetes.* . 2 Specifies the exact location where the pattern needs to be matched, for example, IMPORT . 3 Checks for specific annotations and their elements, such as name and value in the Java code using a query. For example, the following query matches the Bean(url = "http://www.example.com") annotation in the method. annotated: pattern: org.framework.Bean elements: - name: url value: "http://www.example.com" The supported locations are the following: CONSTRUCTOR_CALL TYPE INHERITANCE METHOD_CALL ANNOTATION IMPLEMENTS_TYPE ENUM_CONSTANT RETURN_TYPE IMPORT VARIABLE_DECLARATION FIELD METHOD dependency The dependency capability enables the provider to find dependencies for a given application. MTA generates a list of the application's dependencies, and you can use this capability to query the list and check whether a certain dependency exists for the application within a given range of the dependency's versions. when: java.dependency: name: "<dependency_name>" 1 upperbound: "<version_string>" 2 lowerbound: "<version_string>" 3 1 Name of the dependency to search for. 2 Upper bound on the version of the dependency. 3 Lower bound on the version of the dependency. 2.1.1.4.1.3. go provider The go provider analyzes Go source code. This provider's capabilities are referenced and dependency . referenced The 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: "<dependency_name>" 1 upperbound: "<version_string>" 2 lowerbound: "<version_string>" 3 1 Name of the dependency to search for. 2 Upper bound on the version of the dependency. 3 Lower bound on the version of the dependency. 2.1.1.4.1.4. dotnet provider The dotnet is an external provider used to analyze .NET and C# source code. Currently, the provider supports the referenced capability. referenced The referenced capability enables the provider to find references in the source code. when: dotnet.referenced: pattern: "<pattern>" 1 namespace: "<namespace>" 2 1 pattern : A regex pattern to match the desired reference. For example, HttpNotFound. 2 namespace : Specifies the namespace to search within. For example, System.Web.Mvc. 2.1.1.4.2. Custom variables Provider conditions can have associated custom variables. You can use custom variables to capture relevant information from the matched line in the source code. The values of these variables are interpolated with data matched in the source code. These values can be used to generate detailed templated messages in a rule's action (see Message actions ). They can be added to a rule in the customVariables field: - ruleID: lang-ref-004 customVariables: - pattern: '([A-z]+)\.get\(\)' 1 name: VariableName 2 message: "Found generic call - {{ VariableName }}" 3 when: java.referenced: location: METHOD_CALL pattern: com.example.apps.GenericClass.get 1 pattern : A regular expression pattern that is matched on the source code line when a match is found. 2 name : The name of the variable that can be used in templates. 3 message : A template for a message using a custom variable. 2.1.1.5. Logical conditions The analyzer provides two basic logical conditions, and and or , which enable you to aggregate results of other conditions and create more complex queries. 2.1.1.5.1. and condition The and condition performs a logical AND operation on the results of an array of conditions. An and condition matches when all of its child conditions match. when: and: - <condition1> - <condition2> Example when: and: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit Conditions can also be nested within other conditions. Example when: and: - and: - go.referenced: "*CustomResourceDefinition*" - java.referenced: pattern: "*CustomResourceDefinition*" - go.referenced: "*CustomResourceDefinition*" 2.1.1.5.2. or condition The or condition performs a logical OR operation on the results of an array of conditions. An or condition matches when any of its child conditions matches. when: or: - <condition1> - <condition2> Example when: or: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit 2.1.2. Rulesets A set of rules forms a ruleset. MTA does not require every rule file to belong to a ruleset, but you can use rulesets to group multiple rules that achieve a common goal and to pass the rules to the rules engine. You can create a ruleset by placing one or more YAML rules in a directory and creating a ruleset.yaml file at the directory root. When you pass this directory as input to the MTA CLI using the --rules option, all rules in this directory are treated as a part of the ruleset defined by ruleset.yaml file. The ruleset.yaml file stores the metadata of the ruleset. name: "Name of the ruleset" 1 description: "Description of the ruleset" labels: 2 - key=val 1 The name must be unique within the provided rulesets. 2 Ruleset labels are inherited by all rules that belong to the ruleset. To execute any application analysis, run the following command. Replace <application_to_analyze> with your application, <output_dir> with the directory of your choice, and <custom_rule_dir> with the custom rulesets file. On initiation, the mta-cli tool determines the type of application and the corresponding provider needed for analysis. It then starts the provider in a container that has the required dependencies and tools. Finally, the provider uses the analyzer to execute a series of rulesets to analyze the source code. 2.2. Creating a basic YAML rule This section describes how to create a basic MTA YAML rule. This assumes that you already have MTA installed. See the MTA CLI Guide for installation instructions. 2.2.1. Creating a basic YAML rule template MTA YAML-based rules have the following basic structure: when(condition) message(message) tag(tags) Procedure In the /home/<USER>/ directory, create a file containing the basic syntax for YAML rules as follows: - category: mandatory description: | <DESCRIPTION TITLE> <DESCRIPTION TEXT> effort: <EFFORT> labels: - konveyor.io/source=<SOURCE_TECH> - konveyor.io/target=<TARGET_TECH> links: - url: <HYPERLINK> title: <HYPERLINK_TITLE> message: <MESSAGE> tag: - <TAG1> - <TAG2> ruleID: <RULE_ID> when: <CONDITIONS> 2.2.2. Creating a basic YAML ruleset template If you want to group multiple similar rules, you can create a ruleset for them by placing their files in a directory and creating a ruleset.yaml file at the directory's root. When you pass this directory as input to the MTA CLI using the --rules option, MTA treats all the files in the directory as belonging to the ruleset defined in the ruleset.yaml file. Procedure Create a template for ruleset.yaml files if you want to pass the entire directory using the --rules option: name: <RULESET_NAME> 1 description: <RULESET_DESCRIPTION> labels: 2 - key=val 1 The name must be unique within the provided rulesets. 2 Ruleset labels are inherited by all rules that belong to the ruleset. 2.2.3. Creating a YAML rule Each rule file contains one or more YAML rules. Every rule comprises metadata, conditions and actions. Procedure Create a when condition. The when condition of a YAML rule can be provider , and or or . Create a provider condition The provider condition is used to define a search query for a specific language provider and to invoke a certain capability of the provider. The condition's general format is <provider_name>.<capability> . The condition also has inner fields to specify details of the search. The way you create a provider condition and its inner fields depends on which provider you use and which capability you invoke. The table below lists the available providers and their capabilities. Select a provider and its capability that suit the purpose of the rule you want to create. This part of the condition does not contain any of the condition's fields yet. Provider Capability Description java referenced Finds references of a pattern, including annotations, with an optional code location for detailed searches dependency Checks whether the application has a given dependency builtin xml Searches XML files using XPath queries json Searches JSON files using JSONPath queries filecontent Searches content in regular files using RegEx patterns file Finds files with names matching a given pattern hasTags Checks whether a tag is created for the application through a tagging rule go referenced Finds references of a pattern dependency Checks whether the application has a given dependency The example below shows a java provider condition that uses the referenced capability. Example when: java.referenced: Add suitable fields to the provider condition. The table below lists all available providers, their capabilities, and their fields. Select the fields that belong to the provider and capability that you have chosen. Note that some fields are mandatory. Provider Capability Field Required? Description java referenced pattern Yes RegEx pattern location No Source code location; see below for a list of all supported search locations annotated No Annotations and their elements (name and value) dependency name Yes Name of the dependency nameregex No RegEx pattern to match the name upperbound No Matches version numbers lower than or equal to lowerbound No Matches version numbers greater than or equal to builtin xml xpath Yes XPath query namespaces No A map to scope down query to namespaces filepaths No Optional list of files to scope down search json xpath Yes XPath query filepaths No Optional list of files to scope down search filecontent pattern Yes RegEx pattern to match in content filePattern No Only searches in files with names matching this pattern file pattern Yes Finds files with names matching this pattern hasTags This is an inline list of string tags. See Tag Actions in Rule Actions for details on tag format. go referenced pattern Yes RegEx pattern dependency name Yes Name of the dependency nameregex No RegEx pattern to match the name upperbound No Matches version numbers lower than or equal to lowerbound No Matches version numbers greater than or equal to The following search locations can be used to scope down java searches: CONSTRUCTOR_CALL TYPE INHERITANCE METHOD_CALL ANNOTATION IMPLEMENTS_TYPE ENUM_CONSTANT RETURN_TYPE IMPORT VARIABLE_DECLARATION The example below shows the when condition of a rule that searches for references of a package. Example when: java.referenced: location: PACKAGE pattern: org.jboss.* Create an AND or OR condition An and condition matches when all of its child conditions match. Create an and condition as follows: when: and: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit An or condition matches when any of its child conditions match. Create an or condition as follows: when: or: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit 2.2.4. Running an analysis using a custom YAML rule To run an analysis, use the --rules option in the CLI. Procedure To use the rules in a single rule file, /home/<USER>/rule.yaml , run the following command: mta-cli analyze --input /home/<USER>/data/ --output /home/<USER>/output/ --rules /home/<USER>/rule.yaml where: /home/<USER>/data/ - the directory of the source code or binary /home/<USER>/output/ - the directory for reports (HTML and YAML) To use multiple rule files, you need to place them in a directory and to add a ruleset.yaml file. Then the directory is treated as a ruleset , and you can pass it as input to the --rules option. Note that if you wish to use the --target or --source option in the CLI, the engine will only select rules that match the label for that target. Therefore, make sure that you have added target or source labels on your rules. See Reserved labels for more details. 2.3. Creating your first YAML rule This section guides you through the process of creating and testing your first MTA YAML-based rule. This assumes that you have already installed MTA. See Installing and running the CLI in the CLI Guide for installation instructions. In this example, you will create a rule to discover instances where an application defines a jboss-web.xml file containing a <class-loading> element and to provide a link to the documentation that describes how to migrate the code. 2.3.1. Creating a YAML file for the rule Create a YAML file for your first rule. 2.3.2. Creating data to test the rule Create jboss-web.xml and pom.xml files in a directory: In the jboss-web.xml file you created, paste the following content: In the pom.xml file you created, paste the following content: 2.3.3. Creating the rule MTA YAML-based rules use the following rule pattern: Procedure In the rule.yaml file you created, paste the following contents: 1 Unique ID for your rule. For example, jboss5-web-class-loading . 2 Text description of the rule. 3 Complete the when block specifying one or more conditions: Use the builtin provider's XML capability because this rule checks for a match in an XML file. To match on the class-loading element that is a child of jboss-web , use the XPath expression jboss-web/web-loading as an XML query. In this case, you need just one condition: 4 Helpful message explaining the migration issue. The message is generated in the report when the rule matches. For example: 5 List of string labels for the rule. 6 Number of expected story points to fix this issue. 7 One or more hyperlinks pointing to documentation around the migration issues that you find. The rule is now complete and looks similar to the following: 2.3.4. Installing the rule Procedure Point the CLI to the rule file you created : 2.3.5. Testing the rule Procedure To test the rule, point the input to the test data you created and pass the rule using the rules option in MTA CLI: 2.3.6. Reviewing the report Review the report to be sure that it provides the expected results. Procedure Once the analysis is complete, the command outputs the path to the HTML report: Open /home/<USER_NAME>/output/static-report/index.html in a web browser. Navigate to the Issues tab in the left menu. Verify that the rule is executed: In the Issues table, type JBoss XML in the search bar. Verify that the issue with the title Find class loading element in JBoss XML file is present in the table. Click the jboss-web.xml link to open the affected file.
ruleId: "unique_id" 1 labels: 2 # 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: 1 3 category: mandatory 4 labels: - "key1=val1" - "key2=val2" labels: - "konveyor.io/key1=val1" labels: - "konveyor.io/key=" labels: - "konveyor.io/key" labels: - konveyor.io/dep-source=internal - konveyor.io/language=java - ruleID: test-rule when: <CONDITION> message: Test rule matched. Please resolve this migration issue. links: - url: "konveyor.io" title: "Short title for the link" tag: - "tag1,tag2,tag3" - "Category=tag4,tag5" - ruleID: test-rule when: <CONDITION> tag: - Language=Golang - Env=production - Source Code when: <condition> <nested-condition> when: <provider_name>.<capability> <input_fields> when: builtin.file: pattern: "<regex_to_match_filenames>" when: builtin.filecontent: filePattern: "<regex_to_match_filenames_to_scope_search>" pattern: "<regex_to_match_content_in_the_matching_files>" when: builtin.xml: xpath: "<xpath_expressions>" 1 filepaths: 2 - "/src/file1.xml" - "/src/file2.xml" when: builtin.json: xpath: "<xpath_expressions>" 1 when: # when more than one tag is given, a logical AND is implied hasTags: 1 - "tag1" - "tag2" when: java.referenced: pattern: "<pattern>" 1 location: "<location>" 2 annotated: "<annotated>" 3 annotated: pattern: org.framework.Bean elements: - name: url value: "http://www.example.com" when: java.dependency: name: "<dependency_name>" 1 upperbound: "<version_string>" 2 lowerbound: "<version_string>" 3 when: go.referenced: "<regex_to_find_reference>" when: go.dependency: name: "<dependency_name>" 1 upperbound: "<version_string>" 2 lowerbound: "<version_string>" 3 when: dotnet.referenced: pattern: "<pattern>" 1 namespace: "<namespace>" 2 - ruleID: lang-ref-004 customVariables: - pattern: '([A-z]+)\.get\(\)' 1 name: VariableName 2 message: "Found generic call - {{ VariableName }}" 3 when: java.referenced: location: METHOD_CALL pattern: com.example.apps.GenericClass.get when: and: - <condition1> - <condition2> when: and: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit when: and: - and: - go.referenced: "*CustomResourceDefinition*" - java.referenced: pattern: "*CustomResourceDefinition*" - go.referenced: "*CustomResourceDefinition*" when: or: - <condition1> - <condition2> when: or: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit name: "Name of the ruleset" 1 description: "Description of the ruleset" labels: 2 - key=val mta-cli analyze --input=<application_to_analyze> --output=<output_dir> --rules=<custom_rule_dir> --enable-default-rulesets=false when(condition) message(message) tag(tags) - category: mandatory description: | <DESCRIPTION TITLE> <DESCRIPTION TEXT> effort: <EFFORT> labels: - konveyor.io/source=<SOURCE_TECH> - konveyor.io/target=<TARGET_TECH> links: - url: <HYPERLINK> title: <HYPERLINK_TITLE> message: <MESSAGE> tag: - <TAG1> - <TAG2> ruleID: <RULE_ID> when: <CONDITIONS> name: <RULESET_NAME> 1 description: <RULESET_DESCRIPTION> labels: 2 - key=val when: java.referenced: when: java.referenced: location: PACKAGE pattern: org.jboss.* when: and: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit when: or: - java.dependency: name: junit.junit upperbound: 4.12.2 lowerbound: 4.4.0 - java.referenced: location: IMPORT pattern: junit.junit mta-cli analyze --input /home/<USER>/data/ --output /home/<USER>/output/ --rules /home/<USER>/rule.yaml mkdir /home/<USER>/rule.yaml mkdir /home/<USER>/data/ touch /home/<USER>/data/jboss-web.xml touch /home/<USER>/data/pom.xml <!DOCTYPE jboss-web PUBLIC "-//JBoss//DTD Web Application 4.2//EN" "http://www.jboss.org/j2ee/dtd/jboss-web_4_2.dtd"> <jboss-web> <class-loading java2ClassLoadingCompliance="false"> <loader-repository> seam.jboss.org:loader=@projectName@ <loader-repository-config>java2ParentDelegation=false</loader-repository-config> </loader-repository> </class-loading> </jboss-web> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>test</groupId> <artifactId>test</artifactId> <version>1.1.0-SNAPSHOT</version> <properties> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> </dependencies> </project> when(condition) perform(action) - ruleID: <UNIQUE_RULE_ID> 1 description: <DESCRIPTION> 2 when: <CONDITION(S)> 3 message: <MESSAGE> 4 labels: <LABELS> 5 effort: <EFFORT> 6 links: - <LINKS> 7 when: builtin.xml: xpath: jboss-web/class-loading message: The class-loading element is no longer valid in the jboss-web.xml file. links: - url: https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.4/html-single/Migration_Guide/index.html#Create_or_Modify_Files_That_Control_Class_Loading_in_JBoss_Enterprise_Application_Platform_6 title: Create or Modify Files That Control Class Loading in JBoss EAP 6 - ruleID: jboss5-web-class-loading description: Find class loading element in JBoss XML file. when: builtin.xml: xpath: jboss-web/class-loading message: The class-loading element is no longer valid in the jboss-web.xml file. effort: 3 links: - url: https://access.redhat.com/documentation/en-US/JBoss_Enterprise_Application_Platform/6.4/html-single/Migration_Guide/index.html#Create_or_Modify_Files_That_Control_Class_Loading_in_JBoss_Enterprise_Application_Platform_6 title: Create or Modify Files That Control Class Loading in JBoss EAP 6 -rules /home/<USER>/rules.yaml mta-cli analyze --input /home/<USER>/data/ --output /home/<USER>/output/ --rules /home/<USER>/rules.yaml INFO[0066] Static report created. Access it at this URL: URL="file:/home/<USER>/output/static-report/index.html"