Skip to content

Commit

Permalink
chore(Apps/CodeStyle): rewrite Ci-codestyle in python (#19714)
Browse files Browse the repository at this point in the history
* initial version

* port most current checks

* allow to specify for each checks the exclude files

* Update _ci-codestyle.py

* fix trailing whitespace check and the error_handler logic

* optimize the script to parse all files only one time

* restore the error handling after that all checks are passed

* fix double blank lines at the end of the file

* improve outputs and the codestyle

* .

* update github workflow to the new script

*drop the old ci-codestyle
*move and rename the python script

* use getcwd instead abspath to define src_directory where the script is launch

* test for github workflow

* few cleanup

* fix the logic with the result output

* remove GetTypeId from the output result

* restore GetTypeId() check

* fix reviews

* remove GetTypeId check for gameobjects

*not currently fixed in the core

* fix type hint for file parameters

* remove the test file
  • Loading branch information
Grimdhex committed Aug 27, 2024
1 parent 126f3a3 commit 574ef52
Show file tree
Hide file tree
Showing 3 changed files with 153 additions and 41 deletions.
6 changes: 5 additions & 1 deletion .github/workflows/codestyle.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,12 @@ jobs:
if: github.repository == 'azerothcore/azerothcore-wotlk'
steps:
- uses: actions/checkout@v4
- name: Setup python
uses: actions/setup-python@v4
with:
python-version: '3.10'
- name: AzerothCore codestyle
run: source ./apps/ci/ci-codestyle.sh
run: python ./apps/codestyle/codestyle.py
- name: C++ Advanced
run: |
sudo apt update -y
Expand Down
40 changes: 0 additions & 40 deletions apps/ci/ci-codestyle.sh

This file was deleted.

148 changes: 148 additions & 0 deletions apps/codestyle/codestyle.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
import io
import os
import sys

# Get the src directory of the project
src_directory = os.path.join(os.getcwd(), 'src')

# Global variables
error_handler = False
results = {
"Multiple blank lines check": "Passed",
"Trailing whitespace check": "Passed",
"GetCounter() check": "Passed",
"GetTypeId() check": "Passed",
"NpcFlagHelpers check": "Passed"
}

# Main function to parse all the files of the project
def parsing_file(directory: str) -> None:
for root, _, files in os.walk(directory):
for file in files:
if not file.endswith('.ico'): # Skip .ico files that cannot be read
file_path = os.path.join(root, file)
file_name = file
try:
with open(file_path, 'r', encoding='utf-8') as file:
multiple_blank_lines_check(file, file_path)
trailing_whitespace_check(file, file_path)
get_counter_check(file, file_path)
if file_name != 'Object.h':
get_typeid_check(file, file_path)
if file_name != 'Unit.h':
npcflags_helpers_check(file, file_path)
except UnicodeDecodeError:
print(f"\nCould not decode file {file_path}")
sys.exit(1)
# Output the results
print("")
for check, result in results.items():
print(f"{check} : {result}")
if error_handler:
print("\nPlease fix the codestyle issues above.")
sys.exit(1)
else:
print(f"\nEverything looks good")

# Codestyle patterns checking for multiple blank lines
def multiple_blank_lines_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
check_failed = False
consecutive_blank_lines = 0
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if line.strip() == '':
consecutive_blank_lines += 1
if consecutive_blank_lines > 1:
print(f"Multiple blank lines found in {file_path} at line {line_number - 1}")
check_failed = True
else:
consecutive_blank_lines = 0
# Additional check for the end of the file
if consecutive_blank_lines >= 1:
print(f"Multiple blank lines found at the end of: {file_path}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["Multiple blank lines check"] = "Failed"

# Codestyle patterns checking for whitespace at the end of the lines
def trailing_whitespace_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if line.endswith(' \n'):
print(f"Trailing whitespace found: {file_path} at line {line_number}")
if not error_handler:
error_handler = True
results["Trailing whitespace check"] = "Failed"

# Codestyle patterns checking for ObjectGuid::GetCounter()
def get_counter_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'ObjectGuid::GetCounter()' in line:
print(f"Please use ObjectGuid::ToString().c_str() instead ObjectGuid::GetCounter(): {file_path} at line {line_number}")
if not error_handler:
error_handler = True
results["GetCounter() check"] = "Failed"

# Codestyle patterns checking for GetTypeId()
def get_typeid_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
check_failed = False
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'GetTypeId() == TYPEID_PLAYER' in line:
print(f"Please use IsPlayer() instead GetTypeId(): {file_path} at line {line_number}")
check_failed = True
if 'GetTypeId() == TYPEID_ITEM' in line:
print(f"Please use IsItem() instead GetTypeId(): {file_path} at line {line_number}")
check_failed = True
if 'GetTypeId() == TYPEID_DYNOBJECT' in line:
print(f"Please use IsDynamicObject() instead GetTypeId(): {file_path} at line {line_number}")
check_failed = True
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["GetTypeId() check"] = "Failed"

# Codestyle patterns checking for NpcFlag helpers
def npcflags_helpers_check(file: io, file_path: str) -> None:
global error_handler, results
file.seek(0) # Reset file pointer to the beginning
check_failed = False
# Parse all the file
for line_number, line in enumerate(file, start = 1):
if 'GetUInt32Value(UNIT_NPC_FLAGS)' in line:
print(
f"Please use GetNpcFlags() instead GetUInt32Value(UNIT_NPC_FLAGS): {file_path} at line {line_number}")
check_failed = True
if 'HasFlag(UNIT_NPC_FLAGS,' in line:
print(
f"Please use HasNpcFlag() instead HasFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
check_failed = True
if 'SetUInt32Value(UNIT_NPC_FLAGS,' in line:
print(
f"Please use ReplaceAllNpcFlags() instead SetUInt32Value(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
check_failed = True
if 'SetFlag(UNIT_NPC_FLAGS,' in line:
print(
f"Please use SetNpcFlag() instead SetFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
check_failed = True
if 'RemoveFlag(UNIT_NPC_FLAGS,' in line:
print(
f"Please use RemoveNpcFlag() instead RemoveFlag(UNIT_NPC_FLAGS, ...): {file_path} at line {line_number}")
# Handle the script error and update the result output
if check_failed:
error_handler = True
results["NpcFlagHelpers check"] = "Failed"

# Main function
parsing_file(src_directory)

0 comments on commit 574ef52

Please sign in to comment.