diff --git a/.github/workflows/awesome_workflow.yml b/.github/workflows/awesome_workflow.yml index 4b21072c..b6bfce48 100644 --- a/.github/workflows/awesome_workflow.yml +++ b/.github/workflows/awesome_workflow.yml @@ -14,9 +14,9 @@ jobs: - uses: actions/checkout@v1 # v2 is broken for git diff - uses: actions/setup-python@v2 - name: requirements - run: | + run: | sudo apt -qq -y update - sudo apt -qq install clang-format + sudo apt -qq install clang-tidy-10 - name: Setup Git Specs run: | git config --global user.name github-actions @@ -26,7 +26,7 @@ jobs: run: | IFS=$'\n' for fname in `find . -type f -name '*.c' -o -name '*.h'` - do + do echo "${fname}" new_fname=`echo ${fname} | tr ' ' '_'` echo " ${new_fname}" @@ -41,73 +41,116 @@ jobs: fi done git commit -am "formatting filenames $GITHUB_SHA" || true - - name: Clang Formatter - run: | - for fname in $(find . -name '*.c' -o -name '*.h') - do - clang-format --verbose -i --style="$line1 $line2 $line3 $line4" "$fname" - done - git commit -am "formatting source-code for $GITHUB_SHA" || true - env: - line1: "{ BasedOnStyle: Google, UseTab: Never," - line2: "IndentWidth: 4, TabWidth: 4, BreakBeforeBraces: Allman," - line3: "AllowShortIfStatementsOnASingleLine: false, IndentCaseLabels: false," - line4: "ColumnLimit: 80, AccessModifierOffset: -4 }" - - name: Git Push - run: git push --force origin HEAD:$GITHUB_REF || true - - name: Update DIRECTORY.md shell: python run: | - import os - from typing import Iterator + import os + from typing import Iterator - URL_BASE = "https://github.com/TheAlgorithms/C/blob/master" - g_output = [] + URL_BASE = "https://github.com/TheAlgorithms/C/blob/master" + g_output = [] - def good_filepaths(top_dir: str = ".") -> Iterator[str]: - cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split()) - for dirpath, dirnames, filenames in os.walk(top_dir): - dirnames[:] = [d for d in dirnames if d[0] not in "._"] - for filename in filenames: - if os.path.splitext(filename)[1].lower() in cpp_exts: - yield os.path.join(dirpath, filename).lstrip("./") + def good_filepaths(top_dir: str = ".") -> Iterator[str]: + cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split()) + for dirpath, dirnames, filenames in os.walk(top_dir): + dirnames[:] = [d for d in dirnames if d[0] not in "._"] + for filename in filenames: + if os.path.splitext(filename)[1].lower() in cpp_exts: + yield os.path.join(dirpath, filename).lstrip("./") - def md_prefix(i): - return f"{i * ' '}*" if i else "\n##" + def md_prefix(i): + return f"{i * ' '}*" if i else "\n##" - def print_path(old_path: str, new_path: str) -> str: - global g_output - old_parts = old_path.split(os.sep) - for i, new_part in enumerate(new_path.split(os.sep)): - if i + 1 > len(old_parts) or old_parts[i] != new_part: - if new_part: - g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}") - return new_path + def print_path(old_path: str, new_path: str) -> str: + global g_output + old_parts = old_path.split(os.sep) + for i, new_part in enumerate(new_path.split(os.sep)): + if i + 1 > len(old_parts) or old_parts[i] != new_part: + if new_part: + g_output.append(f"{md_prefix(i)} {new_part.replace('_', ' ').title()}") + return new_path - def build_directory_md(top_dir: str = ".") -> str: - global g_output - old_path = "" - for filepath in sorted(good_filepaths(), key=str.lower): - filepath, filename = os.path.split(filepath) - if filepath != old_path: - old_path = print_path(old_path, filepath) - indent = (filepath.count(os.sep) + 1) if filepath else 0 - url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20") - filename = os.path.splitext(filename.replace("_", " ").title())[0] - g_output.append(f"{md_prefix(indent)} [{filename}]({url})") - return "# List of all files\n" + "\n".join(g_output) + def build_directory_md(top_dir: str = ".") -> str: + global g_output + old_path = "" + for filepath in sorted(good_filepaths(), key=str.lower): + filepath, filename = os.path.split(filepath) + if filepath != old_path: + old_path = print_path(old_path, filepath) + indent = (filepath.count(os.sep) + 1) if filepath else 0 + url = "/".join((URL_BASE, filepath, filename)).replace(" ", "%20") + filename = os.path.splitext(filename.replace("_", " ").title())[0] + g_output.append(f"{md_prefix(indent)} [{filename}]({url})") + return "# List of all files\n" + "\n".join(g_output) - with open("DIRECTORY.md", "w") as out_file: - out_file.write(build_directory_md(".") + "\n") - - name: Update DIRECTORY.md + with open("DIRECTORY.md", "w") as out_file: + out_file.write(build_directory_md(".") + "\n") + - name: Commit DIRECTORY.md run: | - cat DIRECTORY.md - git config --global user.name github-actions - git config --global user.email '${GITHUB_ACTOR}@users.noreply.github.com' - git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git diff DIRECTORY.md git add DIRECTORY.md - git commit -am "updating DIRECTORY.md" || true + git commit -m "updating DIRECTORY.md" || true + - name: Get file changes + run: | + git remote -v + git branch + git remote set-url origin https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/$GITHUB_REPOSITORY + git diff --diff-filter=dr --name-only origin/master > git_diff.txt + echo "Files changed-- `cat git_diff.txt`" + - name: Configure for static lint checks + # compiling first gives clang-tidy access to all the header files and settings used to compile the programs. + # This will check for macros, if any, on linux and not for Windows. But the use of portability checks should + # be able to catch any errors for other platforms. + run: cmake -B build -S . -DCMAKE_EXPORT_COMPILE_COMMANDS=ON + - name: Lint modified files + shell: python + run: | + import os + import subprocess + import sys + + print("Python {}.{}.{}".format(*sys.version_info)) # Python 3.8 + with open("git_diff.txt") as in_file: + modified_files = sorted(in_file.read().splitlines()) + print("{} files were modified.".format(len(modified_files))) + + cpp_exts = tuple(".c .c++ .cc .cpp .cu .cuh .cxx .h .h++ .hh .hpp .hxx".split()) + cpp_files = [file for file in modified_files if file.lower().endswith(cpp_exts)] + print(f"{len(cpp_files)} C++ files were modified.") + if not cpp_files: + sys.exit(0) + + for cpp_file in cpp_files: + subprocess.run(["clang-tidy-10", "--fix", "-p=build", cpp_file, "--"], + check=True, text=True, stderr=subprocess.STDOUT) + + # print("g++:") + # compile_exts = tuple(".c .c++ .cc .cpp .cu .cxx".split()) + # compile_files = [file for file in cpp_files if file.lower().endswith(compile_exts)] + # for cpp_file in cpp_files: + # subprocess.run(["g++", cpp_file], check=True, text=True) + + upper_files = [file for file in cpp_files if file != file.lower()] + if upper_files: + print(f"{len(upper_files)} files contain uppercase characters:") + print("\n".join(upper_files) + "\n") + + space_files = [file for file in cpp_files if " " in file or "-" in file] + if space_files: + print(f"{len(space_files)} files contain space or dash characters:") + print("\n".join(space_files) + "\n") + + nodir_files = [file for file in cpp_files if file.count(os.sep) != 1] + if nodir_files: + print(f"{len(nodir_files)} files are not in one and only one directory:") + print("\n".join(nodir_files) + "\n") + + bad_files = len(upper_files + space_files + nodir_files) + if bad_files: + sys.exit(bad_files) + - name: Commit and push changes + run: | + git commit -am "clang-tidy fixes for $GITHUB_SHA" || true git push --force origin HEAD:$GITHUB_REF || true build: