diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 859e26defc..d893e8e3f7 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -33,6 +33,18 @@ jobs: - name: Search for invalid screenshot files run: ./tools/test/checkInvalidScreenshots.py + checkDependencies: + name: Search for invalid dependencies + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Set up Python 3.12 + uses: actions/setup-python@v5 + with: + python-version: 3.12 + - name: Search for invalid dependencies + run: ./tools/dependencies/checkDependencies.py + # Code checks konsist: name: Konsist tests diff --git a/tools/dependencies/checkDependencies.py b/tools/dependencies/checkDependencies.py new file mode 100755 index 0000000000..c489510bdd --- /dev/null +++ b/tools/dependencies/checkDependencies.py @@ -0,0 +1,82 @@ +#!/usr/bin/env python3 + +import os +import subprocess + + +def getProjectDependencies(): + print("=> Computing dependencies...") + command = subprocess.run( + ["./gradlew :app:dependencies |grep project"], + shell=True, + capture_output=True, + text=True, + ) + data = command.stdout + # Remove the trailing info like "(*)" + result = list(map(lambda x: x.split(" (")[0], data.split("\n"))) + # Filter out comment line + result = list(filter(lambda x: "---" in x, result)) + return result + + +def checkThatModulesExist(dependencies): + print("=> Checking that all modules exist...") + error = 0 + modules = set() + for line in dependencies: + if line: + line = line.split(" ") + for elem in line: + if ":" in elem: + modules.add(elem) + for module in modules: + path = "." + module.replace(":", "/") + "/build.gradle.kts" + if not os.path.exists(path): + error += 1 + print("Error: there is at least one dependency to '" + module + "' but the module does not exist.") + print(" Please remove occurrence(s) of 'implementation(projects" + module.replace(":", ".") + ")'.") + return error + + +def checkThatThereIsNoTestDependency(dependencies): + print("=> Checking that there are no test dependencies...") + errors = set() + currentProject = "" + for line in dependencies: + if line.startswith("+--- project "): + currentProject = line.split(" ")[2] + else: + if ":test" in currentProject: + continue + else: + subProject = line.split(" ")[-1] + if subProject.endswith(":test") or ":tests:" in subProject: + error = "Error: '" + currentProject + "' depends on the test project '" + subProject + "'\n" + error += " Please replace occurrence(s) of 'implementation(projects" + subProject.replace(":", ".") + ")'" + error += " with 'testImplementation(projects" + subProject.replace(":", ".") + ")'." + errors.add(error) + for error in errors: + print(error) + return len(errors) + + +def main(): + dependencies = getProjectDependencies() + # for dep in dependencies: + # print(dep) + errors = 0 + errors += checkThatModulesExist(dependencies) + errors += checkThatThereIsNoTestDependency(dependencies) + print() + if (errors == 0): + print("All checks passed successfully.") + elif (errors == 1): + print("Please fix the error above.") + else: + print("Please fix the " + str(errors) + " errors above.") + exit(errors) + + +if __name__ == "__main__": + main()