As software projects expand in size and complexity, maintaining consistent code standards becomes crucial. These code standards enhance the security, readability, extensibility, and maintainability of software projects. Building on a previous post, we will demonstrate how to use the SASjs library in conjunction with GitHub actions to ensure consistent SAS code quality throughout a repository.

Why enforce coding standards?

  • Security: Consistent coding practices help prevent vulnerabilities and ensure that security measures are uniformly applied across the codebase.
  • Readability: Improved readability makes it easier for developers to understand and review each other’s code, facilitating effective collaboration and onboarding new team members.
  • Extensibility: Standardized code allows developers to add new features or modify existing ones with minimal disruption, ensuring the codebase can evolve smoothly over time.
  • Maintainability: Consistent coding practices reduce code complexity, making it easier to debug, update, and refactor, ultimately leading to a more stable and reliable software product.

Checking for SAS Code Standard Violations with a SASjs Lint

To begin using SASjs to lint our code, we need to install it. SASjs is available through the Node Package Manager (NPM). Follow these steps for installation:

    1. Install NodeJS
    2. Navigate to your project in a CLI and run sasjs lint

Configuring SASjs to use your Code Standards

To configure SASjs to lint with your rules, you must set up a .sasjs file in your project’s home directory. The options available are listed in Table 1.

Option Name Type Default Description
noGremlins Boolean True Don’t allow invisible characters
allowedGremlins List of strings None Hex codes representing allowed gremlins
defaultHeader String None A default header to be added to files when sasjs lint fix is run
hasDoxygenHeader Boolean True Identifies where a doxygen header does not begin in line 1
hasMacroNameInMend Boolean True Checks if the macro name is in the %mend statement
hasMacroParentheses Boolean True Checks if there are spaces between the macro name and the opening parentheses
hasRequiredMacroOptions Boolean False Checks if macros have the options listed in requiredMacroOptions
requiredMacroOptions List of Strings None Macro options to enforce with hasRequiredMacroOptions
ignoreList List of Strings None List of files or directories to ignore
indentationMultiple Integer 2 Check to ensure the number of leading spaces is divided evenly by this number
lineEndings String “off” Check the line endings to ensure files are configured correctly. Options (lf, crlf, off)
lowerCaseFileNames Boolean True Checks that file names are always lowercase
maxDataLineLength Integer 80 Maximum line length for Data lines. Overrides maxLineLength
maxHeaderLineLength Integer 80 Maximum line length for the program header. Overrides maxLineLength
maxLineLength Integer 80 Maximum line length.
noEncodedPasswords Boolean True Ensures no rows contain a sas00X or sasenc type password
noNestedMacros Boolean True Checks if macros are defined inside another macro
noSpacesInFileNames Boolean True Checks if any file names have spaces in them
noTabs Boolean True Makes sure no tabs are used
noTrailingSpaces Boolean True Checks for lines with trailing spaces
severityLevel Dict Allows the user to set the severity level to “warn” or “error” for each option

Table 1: List of linting options provided by SASJS

An example .sasjs configuration for the default values is displayed here:

{
"hasDoxygenHeader": true,
"hasMacroNameInMend": true,
"hasMacroParentheses": true,
"ignoreList": ["sasjsbuild/", "sasjsresults/"],
"indentationMultiple": 2,
"lineEndings": "off",
"lowerCaseFileNames": true,
"maxDataLineLength": 80,
"maxHeaderLineLength": 80,
"maxLineLength": 80,
"noEncodedPasswords": true,
"noNestedMacros": true,
"noGremlins": true,
"noSpacesInFileNames": true,
"noTabs": true,
"noTrailingSpaces": true,
"defaultHeader": "/** Default File Header Here **/",
"severityLevel": {
    "hasDoxygenHeader": "warn",
    "maxLineLength": "warn",
    "noTrailingSpaces": "error"
  }
}

Using GitHub Actions to Ensure Code Standards in a Protected Branch

Now we are ready to set up checks in GitHub. This will ensure the code that throws a linting error based on our configuration does not get merged into the main branch.

  1. In the .github/workflows directory, create a file sasjs-lint.yaml
  2. Copy the following into your sasjs-lint.yaml file if you are using the default git hub run environments,:
    •	on:
    •	  pull_request:
    •	    branches:
    •	      - main
    •	      - release*
    •	
    •	jobs:
    •	  build:
    •	    runs-on: ubuntu-latest
    •	
    •	    strategy:
    •	      matrix:
    •	        node-version: [lts/*]
    •	
    •	    steps:
    •	      - uses: actions/checkout@v2
    •	      - name: Use Node.js ${{ matrix.node-version }}
    •	        uses: actions/setup-node@v2
    •	        with:
    •	          node-version: ${{ matrix.node-version }}
    •	          cache: npm
    •	      - name: Check Code Style
    •	        run: npm run lint
  3. If you are using a custom build that already contains sasjs/cli you can use the following:
    4.	name: sasjs-lint
    5.	on:
    6.	  pull_request:
    7.	    branches:
    8.	      - main
    9.	      - release*
    10.	
    11.	jobs:
    12.	  sasjs-lint:
    13.	    runs-on: custom-build
    14.	
    15.	    container:
    16.	      image: custom-image
    17.	      options: --user root
    18.	
    19.	    steps:
    20.	      - uses: actions/checkout@v2
    21.	      - name: Run the lint (code quality) check
    22.	        run: sasjs lint

For any pull request targeting the main branch or a release branch, if a setting with a severity level marked as “error” is triggered, the workflow will fail and block the process. This will prevent merging any code that does not match the designated standards.

Summary

Using SASjs, we can customize our SAS code standards. We can then leverage GitHub Actions to ensure that any code merged into our protected branches meets these standards. This will allow us to improve the security, readability, extensibility, and maintainability of our code.




Source link


administrator