From 9c279444df6d458c1881fe8e5444a7ac07026cba Mon Sep 17 00:00:00 2001 From: Muhammad Umar Khan <42294172+mumarkhan999@users.noreply.github.com> Date: Wed, 7 Dec 2022 12:07:09 +0500 Subject: [PATCH] build: add import linter check (#31062) * build: add import linter check --- .github/workflows/lint-imports.yml | 48 ++++++++++++++++++++++++++++++ Makefile | 3 ++ requirements/edx/development.txt | 8 +++++ requirements/edx/testing.in | 1 + requirements/edx/testing.txt | 6 ++++ setup.cfg | 26 ++++++++++++++++ 6 files changed, 92 insertions(+) create mode 100644 .github/workflows/lint-imports.yml diff --git a/.github/workflows/lint-imports.yml b/.github/workflows/lint-imports.yml new file mode 100644 index 000000000000..8f9a0bd2e545 --- /dev/null +++ b/.github/workflows/lint-imports.yml @@ -0,0 +1,48 @@ +name: Lint Python Imports + +on: pull_request + +jobs: + + lint-imports: + name: Lint Python Imports + runs-on: ubuntu-20.04 + + steps: + - name: Check out branch + uses: actions/checkout@v2 + + - name: Set up Python + uses: actions/setup-python@v2 + with: + python-version: '3.8' + + - name: Install system requirements + run: sudo apt update && sudo apt install -y libxmlsec1-dev + + - name: Install pip + run: python -m pip install -r requirements/pip.txt + + - name: Get pip cache dir + id: pip-cache-dir + run: echo "::set-output name=dir::$(pip cache dir)" + + - name: Cache pip dependencies + id: cache-dependencies + uses: actions/cache@v2 + with: + path: ${{ steps.pip-cache-dir.outputs.dir }} + key: ${{ runner.os }}-pip-${{ hashFiles('requirements/edx/development.txt') }} + restore-keys: ${{ runner.os }}-pip- + + - name: Install python dependencies + run: pip install -r requirements/edx/development.txt + + # As long there are sub-projects[1] in edx-platform, we analyze each + # project separately here, in order to make import-linting errors easier + # to pinpoint. + # + # [1] https://openedx.atlassian.net/browse/BOM-2579 + + - name: Analyze imports (repo root) + run: make lint-imports diff --git a/Makefile b/Makefile index d2116644b232..dd97cbb6b960 100644 --- a/Makefile +++ b/Makefile @@ -175,6 +175,9 @@ docker_push: docker_tag docker_auth ## push to docker hub docker push "openedx/cms-dev:latest" docker push "openedx/cms-dev:${GITHUB_SHA}" +lint-imports: + lint-imports + # WARNING (EXPERIMENTAL): # This installs the Ubuntu requirements necessary to make `pip install` and some other basic # dev commands to pass. This is not necessarily everything needed to get a working edx-platform. diff --git a/requirements/edx/development.txt b/requirements/edx/development.txt index 398c4f7be885..6b09651053e4 100644 --- a/requirements/edx/development.txt +++ b/requirements/edx/development.txt @@ -173,6 +173,7 @@ click==8.1.3 # code-annotations # edx-django-utils # edx-lint + # import-linter # nltk # pact-python # pip-tools @@ -750,6 +751,10 @@ geoip2==4.6.0 # via -r requirements/edx/testing.txt glob2==0.7 # via -r requirements/edx/testing.txt +grimp==1.3 + # via + # -r requirements/edx/testing.txt + # import-linter gunicorn==20.1.0 # via -r requirements/edx/testing.txt h11==0.14.0 @@ -776,6 +781,8 @@ idna==3.4 # yarl imagesize==1.4.1 # via sphinx +import-linter==1.3.0 + # via -r requirements/edx/testing.txt importlib-metadata==5.0.0 # via # -r requirements/edx/testing.txt @@ -1577,6 +1584,7 @@ typing-extensions==4.4.0 # -r requirements/edx/testing.txt # astroid # django-countries + # import-linter # mypy # pydantic # pylint diff --git a/requirements/edx/testing.in b/requirements/edx/testing.in index ced145bbf0e3..93310adc88f1 100644 --- a/requirements/edx/testing.in +++ b/requirements/edx/testing.in @@ -28,6 +28,7 @@ factory-boy # Library for creating test fixtures, used in many tes # Pinning the freezegun version because 0.3.13 is causing failures which have also been reported on the git repo by public. freezegun # Allows tests to mock the output of assorted datetime module functions httpretty # Library for mocking HTTP requests, used in many tests +import-linter # Tool for making assertions about which modules can import which others isort # For checking and fixing the order of imports pycodestyle # Checker for compliance with the Python style guide (PEP 8) polib # Library for manipulating gettext translation files, used to test paver i18n commands diff --git a/requirements/edx/testing.txt b/requirements/edx/testing.txt index 3c445394be9c..50c0373468e8 100644 --- a/requirements/edx/testing.txt +++ b/requirements/edx/testing.txt @@ -163,6 +163,7 @@ click==8.1.3 # code-annotations # edx-django-utils # edx-lint + # import-linter # nltk # pact-python # user-util @@ -720,6 +721,8 @@ geoip2==4.6.0 # via -r requirements/edx/base.txt glob2==0.7 # via -r requirements/edx/base.txt +grimp==1.3 + # via import-linter gunicorn==20.1.0 # via -r requirements/edx/base.txt h11==0.14.0 @@ -742,6 +745,8 @@ idna==3.4 # requests # snowflake-connector-python # yarl +import-linter==1.3.0 + # via -r requirements/edx/testing.in importlib-metadata==5.0.0 # via # -r requirements/edx/base.txt @@ -1464,6 +1469,7 @@ typing-extensions==4.4.0 # -r requirements/edx/base.txt # astroid # django-countries + # import-linter # pydantic # pylint # snowflake-connector-python diff --git a/setup.cfg b/setup.cfg index a626677f7a88..72a2d296e541 100644 --- a/setup.cfg +++ b/setup.cfg @@ -47,3 +47,29 @@ multi_line_output=3 skip= envs migrations + +[importlinter] +root_packages = + lms + cms +include_external_packages = True + +[importlinter:contract:1] +name = lms and cms are independent +type = independence +modules = + lms + cms +ignore_imports = + # lms side imports that we are ignoring for now + lms.djangoapps.course_home_api.outline.tests.test_view -> cms.djangoapps.contentstore.outlines + lms.djangoapps.courseware.plugins -> cms.djangoapps.contentstore.utils + lms.djangoapps.course_home_api.tests.utils -> cms.djangoapps.contentstore.outlines + # cms side imports that we are ignoring for now + cms.djangoapps.contentstore.views.tests.test_item -> lms.djangoapps.lms_xblock.mixin + cms.envs.common -> lms.envs.common + cms.djangoapps.contentstore.signals.handlers -> lms.djangoapps.grades.api + cms.djangoapps.contentstore.course_group_config -> lms.lib.utils + cms.djangoapps.contentstore.views.preview -> lms.djangoapps.lms_xblock.field_data + cms.envs.common -> lms.djangoapps.lms_xblock.mixin + cms.envs.test -> lms.envs.test