DevOps for SAP is having a moment. More and more elite organizations and prominent developers are embracing the benefits that come from applying modern development principles to ABAP development. The journey is not easy, but it is worthwhile, and taking it one step at a time makes it significantly easier. One small step is starting with implementing a linter on your ABAP code.
What is a linter?
A linter is a tool that analyzes source code to identify potential errors, bugs, or issues that can be detected through static analysis.
When you write a program, you write a bunch of instructions for the computer to follow. These instructions have to be written a certain way, or the program might not work as expected. Static analysis checks the instructions to make sure they are written correctly and follow the rules.
Linter tools are robotic helpers, typically designed to analyze source code against a set of pre-defined rules or guidelines specific to the language and development context. For example, a linter for ABAP might look for common errors like unused variables or missing periods. By finding and fixing these mistakes early, the programmer can ensure that the program works how it’s supposed to when it’s run.
abaplint is a powerful and flexible linter for SAP. It was created by Lars Hvam, the trailblazer of the open-source ABAP movement. So yes, abaplint is also open source.
Why do I need it?
If your organization cares about providing a superior user experience to your customers, you need dependable software. Dependable software requires high-quality and maintainable code, and abaplint (or any ABAP linter) helps you achieve this.
- Improved code quality: abaplint can help identify potential issues and violations of best practices in your ABAP code, allowing you to address these issues and improve the overall quality of your code.
- Consistency: abaplint can help ensure that your code follows a consistent style and structure, improving readability and maintainability.
- Customizability: abaplint is highly customizable, allowing you to configure the tool to suit your specific needs and requirements.
- Integration: abaplint can be integrated into your development workflow, allowing you to automatically check your code for potential issues as part of your testing processes.
Who uses it?
Linters are prevalent outside of SAP development. Within SAP development, abaplint is used by high-performing teams that need to leverage the power of automation to help them be more efficient.
When is the best time to implement it?
Now. 🙂
Since the rules are configurable, you can quickly get started with a small ruleset and continue expanding the rules as needed.
How do I get started?
abaplint runs by checking ABAP code that is serialized using abapGit. For this getting started guide, I will only demonstrate how to run abaplint on GitHub (Continuous Integration Setup). For details on other setups, check the abaplint on GitHub.
If your code is not yet on GitHub, you need abapGit. There are several resources on how to do this, Documentation – abapGit or Video SAP – Install abapGit in 2022
Once your code is on GitHub, you need to do three things.
- Add the workflow configuration,
abaplint.yml
- Update the repository “Workflow permissions”
- Add an abaplint configuration file
abaplint.jsonc
1. Workflow Configuration
Create a file in the following path your-repository/.github/workflows/abaplint.yml
Add the contents below.
name: abaplint
on: [push, pull_request]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: abaplint
uses: abaplint/actions-abaplint@main
# GITHUB_TOKEN in forked repositories is read-only
# https://help.github.com/en/actions/reference/events-that-trigger-workflows#pull-request-event-pull_request
if: ${{ github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
Alternate Setups
For more information on configuration, refer to the abaplint documentation for Continuous Integration.
You can also easily set up your workflow by subscribing to the app on the GitHub Marketplace https://github.com/marketplace/abaplint.
2. Workflow permissions
From the repository page, go to Settings, Actions, General.
Update the Workflow permissions to “Read and write permissions”
3. Configuration File
Let’s add the abaplint configuration. Below is an example file.
{
"global": {
"files": "/src/**/*.*"
},
"dependencies": [
{
"url": "https://github.com/abaplint/deps",
"folder": "/deps",
"files": "/src/**/*.*"
}
],
"syntax": {
"version": "v702",
"errorNamespace": "^(Z|Y|LCL_|TY_|LIF_)"
},
"rules": {
"exporting": true,
"local_class_naming": {
"exclude": [],
"severity": "Error",
"patternKind": "required",
"ignoreNames": [],
"ignorePatterns": [],
"local": "^LCL_.+$",
"exception": "^LCX_.+$",
"test": "^LTCL_.+$"
},
"method_parameter_names": {
"exclude": [],
"severity": "Error",
"patternKind": "required",
"ignoreNames": [],
"ignorePatterns": [],
"ignoreExceptions": true,
"importing": "^I._.+$",
"returning": "^R._.+$",
"changing": "^C._.+$",
"exporting": "^E._.+$"
},
"object_naming": {
"exclude": [],
"severity": "Error",
"patternKind": "required",
"ignoreNames": [],
"ignorePatterns": [],
"clas": "^ZC(L|X)",
"intf": "^ZIF",
"prog": "^Z",
"fugr": "^Z",
"tabl": "^Z",
"ttyp": "^Z",
"dtel": "^Z",
"doma": "^Z",
"msag": "^Z",
"tran": "^Z",
"enqu": "^EZ",
"auth": "^Z",
"pinf": "^Z",
"idoc": "^Z",
"xslt": "^Z",
"ssfo": "^Z",
"ssst": "^Z",
"shlp": "^Z"
},
"selection_screen_naming": {
"exclude": [],
"severity": "Error",
"patternKind": "required",
"ignoreNames": [],
"ignorePatterns": [],
"parameter": "^P_.+$",
"selectOption": "^S_.+$",
"screenElement": "^SC_.+$"
},
"types_naming": {
"exclude": [],
"severity": "Error",
"pattern": "^TY_.+$"
},
"unused_variables": true
}
}
- The “global” property contains a “files” property that specifies the directory
("/src/**/*.*")
that contains your SAP code. - The “dependencies” property contains an array of objects that specify external dependencies that abaplint requires.
- The “syntax” property contains a “version” property that specifies the SAP_BASIS version of the syntax that abaplint should use, and an “errorNamespace” property specifies a regular expression for what objects to check.
- The “rules” property contains a set of key-value pairs that specify various rules that should be applied by abaplint. Each key represents a rule name, and the value defines whether the rule should be enabled.
I’ll focus on the rules property in this post. abaplint has over 150 rules that you can enable. If you do not include a rule in your configuration, it is disabled. To view all of the rules, visit https://rules.abaplint.org.
Consider the first rule in the abaplint.jsonc
file above.
Rule: exporting
Description: Detects EXPORTING statements which can be omitted.
Examples:
* Bad example
call_method( EXPORTING foo = bar ).
* Good example
call_method( foo = bar ).
You can see how this check is helpful in keeping your code clean and avoiding needlessly long syntax. This also conforms with the recommendation for EXPORT in the SAP Clean ABAP Style Guide.
Let’s take a look at what that would look like when abaplint is triggered.
I can update my code to follow the Clean ABAP Style Guide.
lo_exporting_parameter->get_parameter( iv_input = 'Hello World' ).
After committing the change, abaplint is automatically triggered again. This time around, everything looks good.
I like starting with a small set of rules and continuously adding more. Chances are that if you have not used a linter, your code will need a lot of changes. If you apply many rules from the beginning, it can get overwhelming trying to fix your code. Once all the checks pass with a given ruleset, I highly recommend you continue adding rules.
Next Steps
Leave a comment if this topic is interesting or if you want to see more advanced scenarios.
Are you using a linter? If so, drop some details of your experience in the comments.
Photo Credits: Duncan Meyer on Unsplash