diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 22f71418a98..d3c00ff86db 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -17,7 +17,7 @@ concurrency: jobs: Sanity_Checks: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: @@ -25,8 +25,14 @@ jobs: - name: Install Dependencies run: | sudo apt-get update - sudo apt-get install -y software-properties-common cppcheck luajit-5.1-dev luarocks mariadb-server-10.6 mariadb-client-10.6 libmariadb-dev-compat binutils-dev - pip install -r tools/requirements.txt + sudo apt-get install -y software-properties-common cppcheck luajit-5.1-dev luarocks mariadb-server-core mariadb-server mariadb-client libmariadb-dev-compat binutils-dev clang-format + + mkdir .venv + python3 -m venv .venv + source .venv/bin/activate + which python + + .venv/bin/pip install -r tools/requirements.txt luarocks install luacheck --local npm install -g diff-so-fancy - id: changed-files @@ -88,15 +94,15 @@ jobs: exit 1 fi exit 0 - - name: CPP Formatting Checks (clang-format-15) + - name: CPP Formatting Checks (clang-format-18) if: always() run: | - clang-format-15 -version + clang-format-18 -version touch cpp_formatting_checks.txt for changed_file in ${{ steps.changed-files.outputs.all }}; do if [[ -f $changed_file ]]; then if [[ $changed_file == *.cpp || $changed_file == *.h ]]; then - clang-format-15 -style=file -i ${changed_file} + clang-format-18 -style=file -i ${changed_file} fi fi done @@ -125,7 +131,8 @@ jobs: if: always() run: | touch lua_checks.txt - python3 tools/ci/lua_stylecheck.py test >> lua_checks.txt + pwd + .venv/bin/python3 tools/ci/lua_stylecheck.py test >> lua_checks.txt for changed_file in ${{ steps.changed-files.outputs.all }}; do if [[ -f $changed_file ]]; then @@ -135,7 +142,7 @@ jobs: fi done - python3 tools/ci/check_lua_binding_usage.py >> lua_checks.txt + .venv/bin/python3 tools/ci/check_lua_binding_usage.py >> lua_checks.txt cat lua_checks.txt if [ -s lua_checks.txt ] @@ -155,7 +162,7 @@ jobs: fi done - python3 tools/price_checker.py >> sql_checks.txt + .venv/bin/python3 tools/price_checker.py >> sql_checks.txt cat sql_checks.txt if [ -s sql_checks.txt ] @@ -181,9 +188,9 @@ jobs: fi exit 0 - Linux_Clang15_64bit: + Linux_Clang18_64bit: needs: Sanity_Checks - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: @@ -199,8 +206,8 @@ jobs: # key: ${{ runner.os }}-clang - name: Configure CMake run: | - export CC=/usr/bin/clang-15 - export CXX=/usr/bin/clang++-15 + export CC=/usr/bin/clang-18 + export CXX=/usr/bin/clang++-18 mkdir -p build cmake -S . -B build - name: Build @@ -216,14 +223,14 @@ jobs: xi_search xi_world - Linux_ClangTidy15_64bit: + Linux_ClangTidy18_64bit: needs: Sanity_Checks - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: # workaround for broken clang on ubuntu runner until fixed: https://github.com/actions/runner-images/issues/8659 - uses: claywar/workaround8649@4892524a133793c85e25513fae79fc968e63877c with: - os: ubuntu-22.04 + os: ubuntu-24.04 - uses: actions/checkout@v3 with: fetch-depth: 1 @@ -238,8 +245,8 @@ jobs: # key: ${{ runner.os }}-clang - name: Configure CMake run: | - export CC=/usr/bin/clang-15 - export CXX=/usr/bin/clang++-15 + export CC=/usr/bin/clang-18 + export CXX=/usr/bin/clang++-18 mkdir -p build cmake -S . -B build -DENABLE_CLANG_TIDY=ON - name: Build @@ -251,9 +258,9 @@ jobs: exit 1 fi - Linux_GCC13_64bit: + Linux_GCC14_64bit: needs: Sanity_Checks - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 steps: - uses: actions/checkout@v3 with: @@ -269,8 +276,8 @@ jobs: # key: ${{ runner.os }}-gcc - name: Configure CMake run: | - export CC=/usr/bin/gcc-13 - export CXX=/usr/bin/g++-13 + export CC=/usr/bin/gcc-14 + export CXX=/usr/bin/g++-14 mkdir -p build CFLAGS=-m64 CXXFLAGS=-m64 LDFLAGS=-m64 cmake -S . -B build - name: Build @@ -346,14 +353,15 @@ jobs: MacOS_64bit: needs: Sanity_Checks # https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md - runs-on: macos-13 + runs-on: macos-14 steps: - uses: actions/checkout@v3 with: fetch-depth: 1 - name: Install Dependencies (Brew) run: | - brew install mariadb zeromq zmq luajit + brew update + brew install mariadb zeromq zmq luajit llvm - name: Configure CMake run: | mkdir -p build @@ -363,8 +371,8 @@ jobs: cmake --build build -j4 Full_Startup_Checks_Linux: - runs-on: ubuntu-22.04 - needs: Linux_Clang15_64bit + runs-on: ubuntu-24.04 + needs: Linux_Clang18_64bit services: mysql: image: mariadb:10.6 @@ -385,8 +393,14 @@ jobs: - name: Install Dependencies run: | sudo apt-get update - sudo apt-get install -y software-properties-common cmake mariadb-client-10.6 libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev luarocks binutils-dev - pip install bcrypt + sudo apt-get install -y software-properties-common cmake mariadb-server-core mariadb-server mariadb-client libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev luarocks binutils-dev + + mkdir .venv + python3 -m venv .venv + source .venv/bin/activate + which python + + .venv/bin/pip install bcrypt - name: Verify MySQL connection from container run: | mysql -h 127.0.0.1 -uroot -proot -e "SHOW DATABASES" @@ -492,7 +506,7 @@ jobs: VALUES(1, 'GodMode', 1);" printf "\nRunning HeadlessXI for 60 seconds\n" - python3 << EOF + .venv/bin/python3 << EOF import time try: from tools.headlessxi.hxiclient import HXIClient @@ -542,8 +556,8 @@ jobs: fi MultiInstance_Startup_Checks_Linux: - runs-on: ubuntu-22.04 - needs: Linux_Clang15_64bit + runs-on: ubuntu-24.04 + needs: Linux_Clang18_64bit services: mysql: image: mariadb:10.6 @@ -564,7 +578,7 @@ jobs: - name: Install Dependencies run: | sudo apt-get update - sudo apt-get install -y software-properties-common cmake mariadb-client-10.6 libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev luarocks binutils-dev + sudo apt-get install -y software-properties-common cmake mariadb-server-core mariadb-server mariadb-client libmariadb-dev-compat libluajit-5.1-dev libzmq3-dev zlib1g-dev libssl-dev luarocks binutils-dev - name: Verify MySQL connection from container run: | mysql -h 127.0.0.1 -uroot -proot -e "SHOW DATABASES" diff --git a/cmake/CompilerWarnings.cmake b/cmake/CompilerWarnings.cmake index bd232685d24..992a559910c 100644 --- a/cmake/CompilerWarnings.cmake +++ b/cmake/CompilerWarnings.cmake @@ -63,6 +63,7 @@ function(set_project_warnings project_name) -Wno-unused-parameter # warn on unused function parameters -Wno-missing-field-initializers -Wno-sign-compare + -Wno-nan-infinity-disabled # TODO: This is good, but it's Clang only # -Wunused-private-field # warn on unused private fields diff --git a/tools/ci/check_lua_binding_usage.py b/tools/ci/check_lua_binding_usage.py index 445df405679..71e3b235505 100644 --- a/tools/ci/check_lua_binding_usage.py +++ b/tools/ci/check_lua_binding_usage.py @@ -130,7 +130,7 @@ def main(): line = line.replace("\n", "") - for match in re.finditer('(?<=:)[^\(\/\\\: "]*', line): + for match in re.finditer(r'(?<=:)[^\(\/\\\: "]*', line): if ( len(match.group()) > 1 and match.group() not in function_names diff --git a/tools/ci/git.sh b/tools/ci/git.sh index dee9f8afdf3..dcde1c16063 100644 --- a/tools/ci/git.sh +++ b/tools/ci/git.sh @@ -78,7 +78,7 @@ for hash, lines in get_commit_messages().items(): # [^ ]*\. : Any number characters that are NOT a space, ending in a period character. # [a-z]{1,3} : 1-3 entries of characters a-z. This is looking for file extensions. # $ : End of string. - for match in re.finditer("^update [^ ]*\.[a-z]{1,3}$", line.lower()): + for match in re.finditer(r"^update [^ ]*\.[a-z]{1,3}$", line.lower()): print_error(hash, lines, line, "Detected automatic commit message (Example: \"Update filename.ext\").\nPlease " "provide a more detailed summary of your changes.") diff --git a/tools/ci/lua_stylecheck.py b/tools/ci/lua_stylecheck.py index 2cccacb4853..c2175fff8c1 100644 --- a/tools/ci/lua_stylecheck.py +++ b/tools/ci/lua_stylecheck.py @@ -118,19 +118,19 @@ def check_table_formatting(self, line): # [ ]{0,} : Any number of spaces # \n : newline character - for _ in re.finditer("[ ]{0,}=[ ]{0,}\{[ ]{0,}\n", line): + for _ in re.finditer(r"[ ]{0,}=[ ]{0,}\{[ ]{0,}\n", line): self.error("Incorrectly defined table") # \{ : Opening curly brace # [^ \n\}] : Match single characters in list: NOT space or NOT newline or NOT closing curly brace - for _ in re.finditer("\{[^ \n\}]", line): + for _ in re.finditer(r"\{[^ \n\}]", line): self.error("Table opened without an appropriate following space or newline") # [^ \n\{] : Match single characters in list: NOT space or NOT newline or NOT opening curly brace # \} : Closing curly brace - for _ in re.finditer("[^ \n\{]\}", line): + for _ in re.finditer(r"[^ \n\{]\}", line): self.error("Table closed without an appropriate preceding space or newline") def check_parameter_padding(self, line): @@ -142,7 +142,7 @@ def check_parameter_padding(self, line): """ # ,[^ \n] : Any comma that does not have space or newline following - for _ in re.finditer(",[^ \n]", line): + for _ in re.finditer(r",[^ \n]", line): self.error("Multiple parameters used without an appropriate following space or newline") def check_conditional_padding(self, line): @@ -150,7 +150,7 @@ def check_conditional_padding(self, line): # lstrip current line to prevent false-positives from indentation code_line = line.lstrip() - if re.search("\s{2,}(and|or)(\s{1,}|$)|\s{1,}(and|or)\s{2,}", code_line): + if re.search(r"\s{2,}(and|or)(\s{1,}|$)|\s{1,}(and|or)\s{2,}", code_line): self.error("Multiple spaces detected around logical operator.") def check_semicolon(self, line): @@ -160,12 +160,12 @@ def check_semicolon(self, line): """ # Ignore strings in line - quote_regex = regex.compile("\"(([^\"\"]+)|(?R))*+\"|\'(([^\'\']+)|(?R))*+\'", re.S) + quote_regex = regex.compile(r"\"(([^\"\"]+)|(?R))*+\"|\'(([^\'\']+)|(?R))*+\'", re.S) removed_quote_str = regex.sub(quote_regex, "", line) # ; : Any line that contains a semicolon. - for _ in re.finditer(";", removed_quote_str): + for _ in re.finditer(r";", removed_quote_str): self.error("Semicolon detected in line.") def check_variable_names(self, line): @@ -178,7 +178,7 @@ def check_variable_names(self, line): # [^(ID)]) : A token that is NOT 'ID' # (?=[A-Z]) : A token that starts with a capital letter - for match in re.finditer("local (?=[^(ID)])(?=[A-Z]){1,}", line): + for match in re.finditer(r"local (?=[^(ID)])(?=[A-Z]){1,}", line): self.error("Capitalised local name") if "local " in line and " =" in line: @@ -206,14 +206,14 @@ def check_operator_padding(self, line): """ # [^ =~\<\>][\=\+\*\~\/\>\<]|[\=\+\*\/\>\<][^ =\n] : Require space before and after >, <, >=, <=, ==, +, *, ~=, / operators or comparators - for _ in re.finditer("[^ =~\<\>][\=\+\*\~\/\>\<]|[\=\+\*\/\>\<][^ =\n]", line): + for _ in re.finditer(r"[^ =~\<\>][\=\+\*\~\/\>\<]|[\=\+\*\/\>\<][^ =\n]", line): self.error("Operator or comparator without padding detected at end of line") # For now, ignore all content in single-line tables to allow for formatting stripped_line = line.lstrip() - brace_regex = regex.compile("\{(([^\}\{]+)|(?R))*+\}", re.S) + brace_regex = regex.compile(r"\{(([^\}\{]+)|(?R))*+\}", re.S) stripped_line = regex.sub(brace_regex, "", stripped_line) - for _ in re.finditer("\s{2,}(>=|<=|==|~=|\+|\*|%|>|<|\^)|(>=|<=|==|~=|\+|\*|%|>|<|\^)\s{2,}", stripped_line): + for _ in re.finditer(r"\s{2,}(>=|<=|==|~=|\+|\*|%|>|<|\^)|(>=|<=|==|~=|\+|\*|%|>|<|\^)\s{2,}", stripped_line): self.error("Excessive padding detected around operator or comparator.") def check_parentheses_padding(self, line): @@ -223,7 +223,7 @@ def check_parentheses_padding(self, line): See: https://github.com/LandSandBoat/server/wiki/Development-Guide#lua-no-excess-whitespace """ - if len(re.findall("\([ ]| [\)]", line)) > 0: + if len(re.findall(r"\([ ]| [\)]", line)) > 0: if not line.lstrip(' ')[0] == '(' and not line.lstrip(' ')[0] == ')': # Ignore large blocks ending or opening self.error("No excess whitespace inside of parentheses or solely for alignment.") @@ -283,7 +283,7 @@ def check_no_function_decl_padding(self, line): See: TBD """ - if re.search("function\s{1,}\(", line): + if re.search(r"function\s{1,}\(", line): self.error("Padding detected between function and opening parenthesis") def check_multiline_condition_format(self, line): @@ -293,7 +293,7 @@ def check_multiline_condition_format(self, line): See: https://github.com/LandSandBoat/server/wiki/Development-Guide#lua-formatting-conditional-blocks """ - stripped_line = re.sub("\".*?\"|'.*?'", "", line) # Ignore data in quotes + stripped_line = re.sub(r"\".*?\"|'.*?'", "", line) # Ignore data in quotes if contains_word('if')(stripped_line) or contains_word('elseif')(stripped_line): condition_start = stripped_line.replace('elseif','').replace('if','').strip() if not 'then' in condition_start and condition_start != '': @@ -367,12 +367,12 @@ def run_style_check(self): continue comment_header = line.rstrip("\n") - if re.search("^-+$", comment_header) and len(comment_header) > 2 and len(comment_header) != 35: + if re.search(r"^-+$", comment_header) and len(comment_header) > 2 and len(comment_header) != 35: # For now, ignore empty comments with only `--` self.error("Standard comment block lines of '-' should be 35 characters.") # Remove in-line comments - code_line = re.sub("(?=--)(.*?)(?=\r\n|\n)", "", line).rstrip() + code_line = re.sub(r"(?=--)(.*?)(?=\r\n|\n)", "", line).rstrip() # Before replacing strings, see if we're only using single quotes and check requires if re.search(r"\"[^\"']*\"(?=(?:[^']*'[^']*')*[^']*$)", code_line): @@ -383,8 +383,8 @@ def run_style_check(self): code_line = code_line.replace("\\'", '') code_line = code_line.replace('\\"', '') - code_line = re.sub('\"([^\"]*?)\"', "strVal", code_line) - code_line = re.sub("\'([^\"]*?)\'", "strVal", code_line) + code_line = re.sub(r'\"([^\"]*?)\"', "strVal", code_line) + code_line = re.sub(r"\'([^\"]*?)\'", "strVal", code_line) # Checks that apply to all lines self.check_table_formatting(code_line) @@ -406,10 +406,10 @@ def run_style_check(self): # Keep track of ID variable assignments and if they are referenced. # TODO: Track each unique variable, and expand this to potentially something # more generic for other tests. - if re.search("ID[ ]+=[ ]+zones\[", code_line): + if re.search(r"ID[ ]+=[ ]+zones\[", code_line): uses_id = True - if uses_id == True and re.search("ID\.", code_line): + if uses_id == True and re.search(r"ID\.", code_line): has_id_ref = True # Multiline conditionals should not have data in if, elseif, or then @@ -441,16 +441,16 @@ def run_style_check(self): if contains_word('then')(code_line): condition_str = full_condition.replace('elseif','').replace('if','').replace('then','').strip() - paren_regex = regex.compile("\((([^\)\(]+)|(?R))*+\)", re.S) + paren_regex = regex.compile(r"\((([^\)\(]+)|(?R))*+\)", re.S) removed_paren_str = regex.sub(paren_regex, "", condition_str) if removed_paren_str == "": self.error("Outer parentheses should be removed in condition") - if len(re.findall("== true|== false|~= true|~= false", condition_str)) > 0: + if len(re.findall(r"== true|== false|~= true|~= false", condition_str)) > 0: self.error("Boolean with explicit value check") - if not in_condition and len(re.findall(" and | or ", condition_str)) > 0 and len(condition_str) > 72: + if not in_condition and len(re.findall(r" and | or ", condition_str)) > 0 and len(condition_str) > 72: self.error("Multiline conditional format required") in_condition = False diff --git a/tools/run_clang_format.bat b/tools/run_clang_format.bat index 923fe6e29c1..2d7c3274a98 100644 --- a/tools/run_clang_format.bat +++ b/tools/run_clang_format.bat @@ -1,5 +1,5 @@ REM Run from repo root -REM Uses clang-format-15 +REM Uses clang-format-18 for /r %cd%\src\ %%f in (*.cpp) do clang-format -style=file -i %%f for /r %cd%\src\ %%f in (*.h) do clang-format -style=file -i %%f diff --git a/tools/run_clang_format.sh b/tools/run_clang_format.sh index eabcab5babe..91facdff77e 100644 --- a/tools/run_clang_format.sh +++ b/tools/run_clang_format.sh @@ -1,3 +1,3 @@ # Run from repo root -for f in $(find src/ -name '*.h' -or -name '*.cpp'); do clang-format-15 -style=file -i $f; done -for f in $(find modules/ -name '*.h' -or -name '*.cpp'); do clang-format-15 -style=file -i $f; done +for f in $(find src/ -name '*.h' -or -name '*.cpp'); do clang-format-18 -style=file -i $f; done +for f in $(find modules/ -name '*.h' -or -name '*.cpp'); do clang-format-18 -style=file -i $f; done